internal static void RemoveAllEventHandlers(Action <EventRegistrationToken> removeMethod) { object instanceKey = GetInstanceKey(removeMethod); System.Collections.Generic.Internal.List <EventRegistrationToken> tokensToRemove = new System.Collections.Generic.Internal.List <EventRegistrationToken>(); // // The whole add/remove code has to be protected by a reader/writer lock // Add/Remove cannot run at the same time with cache cleanup but Add/Remove can run at the same time // s_eventCacheRWLock.EnterReadLock(); try { EventCacheEntry registrationTokens = GetEventRegistrationTokenTableNoCreate(instanceKey, removeMethod); if (registrationTokens == null) { // We have no information regarding this particular instance (IUnknown*/type) - just return // This is necessary to avoid leaking empty dictionary/conditionalWeakTables for this instance return; } try { registrationTokens.LockAcquire(); // Copy all tokens to tokensToRemove array which later we'll call removeMethod on // outside this lock foreach (KeyValuePair <object, EventRegistrationTokenListWithCount> item in registrationTokens.registrationTable) { item.Value.CopyTo(tokensToRemove); } // Clear the table - at this point all event handlers are no longer in the cache // but they are not removed yet registrationTokens.registrationTable.Clear(); #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] Cache cleared for managed instance = " + instanceKey + "\n"); #endif } finally { registrationTokens.LockRelease(); } } finally { s_eventCacheRWLock.ExitReadLock(); } // // Remove all handlers outside the lock // #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] Start removing all events for instance = " + instanceKey + "\n"); #endif CallRemoveMethods(removeMethod, tokensToRemove); #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] Finished removing all events for instance = " + instanceKey + "\n"); #endif }
// // Call removeMethod on each token and aggregate all exceptions thrown from removeMethod into one in case of failure // internal static void CallRemoveMethods(Action <EventRegistrationToken> removeMethod, System.Collections.Generic.Internal.List <EventRegistrationToken> tokensToRemove) { System.Collections.Generic.Internal.List <Exception> exceptions = new System.Collections.Generic.Internal.List <Exception>(); for (int i = 0; i < tokensToRemove.Count; i++) { try { removeMethod(tokensToRemove[i]); } catch (Exception ex) { exceptions.Add(ex); } #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] Event unsubscribed for token = " + token.m_value + "\n"); #endif } if (exceptions.Count > 0) #if false { throw new AggregateException(exceptions.ToArray()); } #else { throw exceptions[0]; } #endif }
public void CopyTo(System.Collections.Generic.Internal.List <EventRegistrationToken> tokens) { tokens.Add(firstToken); if (restTokens != null) { for (int i = 0; i < restTokens.Count; i++) { tokens.Add(restTokens[i]); } } }
// Push a new token into this list // Returns true if you need to copy back this list into the dictionary (so that you // don't lose change outside the dictionary). false otherwise. public bool Push(EventRegistrationToken token) { bool needCopy = false; if (restTokens == null) { restTokens = new System.Collections.Generic.Internal.List <EventRegistrationToken>(); needCopy = true; } restTokens.Add(token); return(needCopy); }
internal static void RemoveAllEventHandlers(Action <EventRegistrationToken> removeMethod) { Debug.Assert(removeMethod != null); object instance = removeMethod.Target; System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList> registrationTokens = GetEventRegistrationTokenTable(instance, removeMethod); System.Collections.Generic.Internal.List <EventRegistrationToken> tokensToRemove = new System.Collections.Generic.Internal.List <EventRegistrationToken>(); try { registrationTokens.LockAcquire(); // Copy all tokens to tokensToRemove array which later we'll call removeMethod on // outside this lock foreach (EventRegistrationTokenList tokens in registrationTokens.Values) { tokens.CopyTo(tokensToRemove); } // Clear the dictionary - at this point all event handlers are no longer in the cache // but they are not removed yet registrationTokens.Clear(); #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] Cache cleared for managed instance = " + instance + "\n"); #endif } finally { registrationTokens.LockRelease(); } // // Remove all handlers outside the lock // #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] Start removing all events for instance = " + instance + "\n"); #endif CallRemoveMethods(removeMethod, tokensToRemove); #if false BCLDebug.Log("INTEROP", "[WinRT_Eventing] Finished removing all events for instance = " + instance + "\n"); #endif }
/// <summary> /// Return the list of IIDs /// Used by IInspectable.GetIIDs implementation for every CCW /// </summary> internal static System.Collections.Generic.Internal.List<Guid> GetIIDs(this RuntimeTypeHandle ccwType) { System.Collections.Generic.Internal.List<Guid> iids = new System.Collections.Generic.Internal.List<Guid>(); // Every CCW implements ICPP iids.Add(Interop.COM.IID_ICustomPropertyProvider); // if there isn't any data about this type, just return empty list if (!ccwType.IsSupportCCWTemplate()) return iids; GetIIDsImpl(ccwType, iids); return iids; }
public void CopyTo(System.Collections.Generic.Internal.List <EventRegistrationToken> tokens) { _tokenList.CopyTo(tokens); }
internal EventRegistrationTokenList(EventRegistrationTokenList list) { firstToken = list.firstToken; restTokens = list.restTokens; }
private System.Collections.Generic.Internal.List <EventRegistrationToken> restTokens; // Rest of the tokens internal EventRegistrationTokenList(EventRegistrationToken token) { firstToken = token; restTokens = null; }