123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- // reference from https://referencesource.microsoft.com/#WindowsBase/Shared/MS/Win32/HandleCollector.cs,d0f99220d8e1b708
- using System;
- using System.Runtime.InteropServices;
- namespace HandyControl.Tools.Interop;
- internal static class HandleCollector
- {
- private static HandleType[] HandleTypes;
- private static int HandleTypeCount;
- private static readonly object HandleMutex = new();
- internal static IntPtr Add(IntPtr handle, int type)
- {
- HandleTypes[type - 1].Add();
- return handle;
- }
- [System.Security.SecuritySafeCritical]
- internal static SafeHandle Add(SafeHandle handle, int type)
- {
- HandleTypes[type - 1].Add();
- return handle;
- }
- internal static void Add(int type)
- {
- HandleTypes[type - 1].Add();
- }
- internal static int RegisterType(string typeName, int expense, int initialThreshold)
- {
- lock (HandleMutex)
- {
- if (HandleTypeCount == 0 || HandleTypeCount == HandleTypes.Length)
- {
- HandleType[] newTypes = new HandleType[HandleTypeCount + 10];
- if (HandleTypes != null)
- {
- Array.Copy(HandleTypes, 0, newTypes, 0, HandleTypeCount);
- }
- HandleTypes = newTypes;
- }
- HandleTypes[HandleTypeCount++] = new HandleType(expense, initialThreshold);
- return HandleTypeCount;
- }
- }
- internal static IntPtr Remove(IntPtr handle, int type)
- {
- HandleTypes[type - 1].Remove();
- return handle;
- }
- [System.Security.SecuritySafeCritical]
- internal static SafeHandle Remove(SafeHandle handle, int type)
- {
- HandleTypes[type - 1].Remove();
- return handle;
- }
- internal static void Remove(int type)
- {
- HandleTypes[type - 1].Remove();
- }
- private class HandleType
- {
- private readonly int _initialThreshHold;
- private int _threshHold;
- private int _handleCount;
- private readonly int _deltaPercent;
- internal HandleType(int expense, int initialThreshHold)
- {
- _initialThreshHold = initialThreshHold;
- _threshHold = initialThreshHold;
- _deltaPercent = 100 - expense;
- }
- internal void Add()
- {
- lock (this)
- {
- _handleCount++;
- var performCollect = NeedCollection();
- if (!performCollect)
- {
- return;
- }
- }
- GC.Collect();
- var sleep = (100 - _deltaPercent) / 4;
- System.Threading.Thread.Sleep(sleep);
- }
- private bool NeedCollection()
- {
- if (_handleCount > _threshHold)
- {
- _threshHold = _handleCount + _handleCount * _deltaPercent / 100;
- return true;
- }
- var oldThreshHold = 100 * _threshHold / (100 + _deltaPercent);
- if (oldThreshHold >= _initialThreshHold && _handleCount < (int) (oldThreshHold * .9F))
- {
- _threshHold = oldThreshHold;
- }
- return false;
- }
- internal void Remove()
- {
- lock (this)
- {
- _handleCount--;
- _handleCount = Math.Max(0, _handleCount);
- }
- }
- }
- }
|