// Remove the delegate handler from the Windows Runtime style event registration by looking for // its token, previously stored via AddEventHandler<T> public static void RemoveEventHandler <T>(Action <EventRegistrationToken> removeMethod, T handler) { if (removeMethod == null) { throw new ArgumentNullException(nameof(removeMethod)); } Contract.EndContractBlock(); // Managed code allows removing a null event handler, the effect is a no-op. To match this behavior // for WinRT events, we simply ignore attempts to remove null. if (handler == null) { return; } // Delegate to managed event registration implementation or native event registration implementation // They have completely different implementation because native side has its own unique problem to solve - // there could be more than one RCW for the same COM object // it would be more confusing and less-performant if we were to merge them together #if !RHTESTCL object target = removeMethod.Target; if (target == null || target is __ComObject) { NativeOrStaticEventRegistrationImpl.RemoveEventHandler <T>(removeMethod, handler); } else #endif ManagedEventRegistrationImpl.RemoveEventHandler <T>(removeMethod, handler); }
public static void RemoveAllEventHandlers(Action <EventRegistrationToken> removeMethod) { if (removeMethod == null) { throw new ArgumentNullException(nameof(removeMethod)); } // Delegate to managed event registration implementation or native event registration implementation // They have completely different implementation because native side has its own unique problem to solve - // there could be more than one RCW for the same COM object // it would be more confusing and less-performant if we were to merge them together #if !RHTESTCL object target = removeMethod.Target; if (target == null || target is __ComObject) { NativeOrStaticEventRegistrationImpl.RemoveAllEventHandlers(removeMethod); } else #endif ManagedEventRegistrationImpl.RemoveAllEventHandlers(removeMethod); }
// Add an event handler to a Windows Runtime style event, such that it can be removed via a delegate // lookup at a later time. This method adds the handler to the add method using the supplied // delegate. It then stores the corresponding token in a dictionary for easy access by RemoveEventHandler // later. Note that the dictionary is indexed by the remove method that will be used for RemoveEventHandler // so the removeMethod given here must match the remove method supplied there exactly. public static void AddEventHandler <T>(Func <T, EventRegistrationToken> addMethod, Action <EventRegistrationToken> removeMethod, T handler) { if (addMethod == null) { throw new ArgumentNullException(nameof(addMethod)); } if (removeMethod == null) { throw new ArgumentNullException(nameof(removeMethod)); } Contract.EndContractBlock(); // Managed code allows adding a null event handler, the effect is a no-op. To match this behavior // for WinRT events, we simply ignore attempts to add null. if (handler == null) { return; } // Delegate to managed event registration implementation or native event registration implementation // They have completely different implementation because native side has its own unique problem to solve - // Managed events are implemented using ConditionalWeakTable which is based on the weak reference of the event itself. // Since the managed event will be alive till the event is used. This is OK. // On the other hand native and static events can't follow the same model as managed object. Since the native event might be alive but the managed __ComObject might // die, a different __ComObject instance might reference the same native event. Or same __ComObject instance might mean a different native event. // and hence they both have different implementations. #if !RHTESTCL object target = removeMethod.Target; if (target == null || target is __ComObject) { NativeOrStaticEventRegistrationImpl.AddEventHandler <T>(addMethod, removeMethod, handler); } else #endif ManagedEventRegistrationImpl.AddEventHandler <T>(addMethod, removeMethod, handler); }