示例#1
0
            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
            }
示例#2
0
        //
        // 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
        }
示例#3
0
            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]);
                    }
                }
            }
示例#4
0
            // 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);
            }
示例#5
0
            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
            }
示例#6
0
        /// <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;
        }
示例#7
0
 public void CopyTo(System.Collections.Generic.Internal.List <EventRegistrationToken> tokens)
 {
     _tokenList.CopyTo(tokens);
 }
示例#8
0
 internal EventRegistrationTokenList(EventRegistrationTokenList list)
 {
     firstToken = list.firstToken;
     restTokens = list.restTokens;
 }
示例#9
0
            private System.Collections.Generic.Internal.List <EventRegistrationToken> restTokens; // Rest of the tokens

            internal EventRegistrationTokenList(EventRegistrationToken token)
            {
                firstToken = token;
                restTokens = null;
            }