/// <summary> /// Cleans up all weak event delegates. Must be done on a regular basis. /// </summary> protected static void GarbageCollect() { int idx = 0; lock (_syncObj) { int max; bool needCleanup = false; while (idx < (max = _delegates.Count)) { max = Math.Min(max, idx + NUM_PASS); for (; idx < max; idx++) { WeakReference wp = _delegates[idx]; WeakEventMulticastDelegate wemd = (WeakEventMulticastDelegate)wp.Target; if (wemd == null) { needCleanup = true; continue; } wemd.GarbageCollectHandlers(); } Monitor.PulseAll(_syncObj); // Interrupt the work to let other threads work } if (needCleanup) { ICollection <WeakReference> oldDelegates = _delegates; _delegates = new List <WeakReference>(oldDelegates.Count); foreach (WeakReference p in oldDelegates) { if (p.Target != null) { _delegates.Add(p); } } } } }