internal void Add(IntPtr handle) {
if( handle == IntPtr.Zero )
{
return;
}
bool performCollect = false;
int currentCount = 0;
lock(this) {
handleCount++;
#if DEBUG_HANDLECOLLECTOR
Debug.Assert(!handles.Contains(handle));
handles.Add(handle);
#endif
performCollect = NeedCollection();
currentCount = handleCount;
}
lock (internalSyncObject){
if (HandleCollector.HandleAdded != null) {
HandleCollector.HandleAdded(name, handle, currentCount);
}
}
if (!performCollect) {
return;
}
if (performCollect) {
#if DEBUG_HANDLECOLLECTOR
Debug.WriteLine("HC> Forcing garbage collect");
Debug.WriteLine("HC> name :" + name);
Debug.WriteLine("HC> threshHold :" + (threshHold).ToString());
Debug.WriteLine("HC> handleCount :" + (handleCount).ToString());
Debug.WriteLine("HC> deltaPercent:" + (deltaPercent).ToString());
#endif
GC.Collect();
// We just performed a GC. If the main thread is in a tight
// loop there is a this will cause us to increase handles forever and prevent handle collector
// from doing its job. Yield the thread here. This won't totally cause
// a finalization pass but it will effectively elevate the priority
// of the finalizer thread just for an instant. But how long should
// we sleep? We base it on how expensive the handles are because the
// more expensive the handle, the more critical that it be reclaimed.
int sleep = (100 - deltaPercent) / 4;
System.Threading.Thread.Sleep(sleep);
}
}