public static EventHandler <E> Unregister <E>(this EventHandler <E> sourceHandler, EventHandler <E> value) where E : EventArgs { if (value == null) { throw new ArgumentNullException("value"); } if (value.Method.IsStatic || value.Target == null) { throw new ArgumentException("Only instance methods are supported.", "value"); } if (sourceHandler != null) { // look for the weak event handler in the invocation list foreach (EventHandler <E> evt in sourceHandler.GetInvocationList()) { IWeakEventHandler <E> weh = evt.Target as IWeakEventHandler <E>; if (weh != null) { object target = weh.Target.Target; if (target != null && ReferenceEquals(target, value.Target)) { return(weh.Handler); } } } } // return the input as the default if we don't find a wrapped event handler return(value); }
/// <summary> /// Sxtesion method for EventHandler<E> /// </summary> /// <typeparam name="E">The type</typeparam> /// <param name="eventHandler">The EventHandler</param> /// <param name="unregister">EventHandler unregister delegate</param> /// <returns>An EventHandler</returns> public static EventHandler <E> MakeWeak <E>(this EventHandler <E> eventHandler, UnregisterCallback <E> unregister) where E : System.EventArgs { if (eventHandler == null) { throw new ArgumentNullException("eventHandler"); } if (eventHandler.Method.IsStatic || eventHandler.Target == null) { throw new ArgumentException("Only instance methods are supported.", "eventHandler"); } Type wehType = typeof(WeakEventHandler <,>).MakeGenericType( eventHandler.Method.DeclaringType, typeof(E)); ConstructorInfo wehConstructor = wehType.GetConstructor(new Type[] { typeof(EventHandler <E>), typeof(UnregisterCallback <E>) }); IWeakEventHandler <E> weh = (IWeakEventHandler <E>)wehConstructor.Invoke( new object[] { eventHandler, unregister }); return(weh.Handler); }
/// <summary> /// Crea un handler debil para eventos de tipo <c>TEventHandler</c>, /// </summary> /// <param name="eventHandler">Handler origen.</param> /// <param name="unregister">Delegado para deregistrar el evento.</param> /// <returns>Handler debil.</returns> public static IWeakEventHandler <TEventHandler> MakeWeak <TEventHandler, TEventArgs>( TEventHandler eventHandler, UnregisterCallback <TEventHandler> unregister) where TEventArgs : EventArgs { Delegate delEventHandler = eventHandler as Delegate; Contract.Requires(delEventHandler != null); // Only instance methods are supported. Contract.Requires(!delEventHandler.Method.IsStatic && delEventHandler.Target != null); Type wehType = typeof(WeakEventHandler <, ,>).MakeGenericType( delEventHandler.Method.DeclaringType, typeof(TEventHandler), typeof(TEventArgs)); ConstructorInfo wehConstructor = wehType.GetConstructor(new[] { typeof(TEventHandler), typeof(UnregisterCallback <TEventHandler>) }); Contract.Assert(wehConstructor != null); IWeakEventHandler <TEventHandler> weh = (IWeakEventHandler <TEventHandler>)wehConstructor.Invoke(new object[] { eventHandler, unregister }); return(weh); }
public static EventHandler <TCustomArgs> MakeWeak <TCustomArgs>(this EventHandler <TCustomArgs> eventHandler, Action <EventHandler <TCustomArgs> > unregister) where TCustomArgs : EventArgs { if (eventHandler == null) { throw new ArgumentNullException("eventHandler"); } if (unregister == null) { throw new ArgumentNullException("unregister"); } if (!IsInstanceMethod(eventHandler)) { throw new ArgumentException("Only instance methods are supported.", "eventHandler"); } // We cannot make anonymous methods (including lambdas) into weak event handlers. Doing so could potentially // allow the anonymous method to be GC'd, since the only thing referring to it would be the weak reference. // This would result in silent failures, as the event handler (the anonymous method) would no longer exist & // therefore never be called. In addition, this would happen somewhat randomly as it's dependent on GC timing. if (IsAnonymousMethod(eventHandler)) { throw new ArgumentException("Cannot create weak event to anonymous method with closure.", "eventHandler"); } // Check to see if we're already weak if (WeakEventHandlerHelpersT <TCustomArgs> .IsWeakEventHandler(eventHandler)) { return(eventHandler); } IWeakEventHandler <TCustomArgs> weh = WeakEventHandlerFactory <TCustomArgs> .Create(eventHandler, unregister); return(weh.HandlerT); }
/// <summary> /// Initializes a new instance of the <see cref="EventItem"/> class. /// </summary> /// <exception cref="InvalidOperationException"> /// Thrown when the requested operation is invalid. /// </exception> /// <param name="handler"> /// The handler. /// </param> public EventItem(EventHandler <TEventArgs> handler) { handler.ArgumentNotNull(nameof(handler)); var d = (Delegate)handler; // will be null for static methods. var target = d.Target; if (ReferenceEquals(target, null)) { // static method. Types are not garbage collected so use a strong reference. _strongEventHandler = handler; } else { var wet = typeof(WeakEventHandler <>).MakeGenericType(typeof(TEventArgs), handler.Method.DeclaringType); var eht = typeof(EventHandler <TEventArgs>); var ctor = wet.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { eht }, null); if (ctor == null) { throw new InvalidOperationException( string.Format( CultureInfo.InvariantCulture, "Could not find a constructor for type '{0}' taking one parameter of type '{1}'", wet.Name, eht.Name)); } _weakEventHandler = (IWeakEventHandler)ctor.Invoke(new object[] { handler }); } }
/// <summary> /// Escucha con un handler debil para eventos de tipo <c>TEventHandler</c>, /// </summary> /// <param name="eventHandler">Handler origen.</param> /// <param name="register">Delegado para registrar el evento.</param> /// <param name="unregister">Delegado para deregistrar el evento.</param> /// <returns>Handler debil.</returns> public static IWeakEventHandler <TEventHandler> WeakListen <TEventHandler, TEventArgs>( TEventHandler eventHandler, RegisterCallback <TEventHandler> register, UnregisterCallback <TEventHandler> unregister) where TEventArgs : EventArgs { IWeakEventHandler <TEventHandler> weak = MakeWeak <TEventHandler, TEventArgs>(eventHandler, unregister); register(weak.Handler); return(weak); }
static WeakEventCleaner() { Thread thread = new Thread(() => { do { Thread.Sleep(Configuration.WeakEventCleanPeriod); int count = _singeWeakEventHandlersQueue.Count; do { _singeWeakEventHandlersQueue.TryDequeue(out var weakEventHandler); if (!weakEventHandler.TryUnsubscribe()) { _singeWeakEventHandlersQueue.Enqueue(weakEventHandler); } count--; } while (count > 0); count = _manyWeakEventHandlersQueue.Count; do { _manyWeakEventHandlersQueue.TryDequeue(out var weakEventHandlers); int removedCount = 0; int weakEventHandlersCount = weakEventHandlers.Count; for (int i = 0; i < weakEventHandlersCount; i++) { IWeakEventHandler weakEventHandler = weakEventHandlers[i - removedCount]; if (weakEventHandler.TryUnsubscribe()) { weakEventHandlers.RemoveAt(i - removedCount); } } if (removedCount < weakEventHandlersCount) { _manyWeakEventHandlersQueue.Enqueue(weakEventHandlers); } count--; } while (count > 0); } while (true); }); thread.IsBackground = true; thread.Name = "ObservableComputations cleaner"; thread.Start(); }
public static EventHandler AsWeak([NotNull] EventHandler handler, Action <EventHandler> unregister) { Requires.NotNull(handler, nameof(handler)); if (handler.Method.IsStatic) { return(handler); } Type t = typeof(WeakEventHandler <>).MakeGenericType(handler.Method.DeclaringType); ConstructorInfo ctor = t.GetConstructor(new Type[] { typeof(EventHandler), typeof(Action <EventHandler>) }); IWeakEventHandler weakHandler = (IWeakEventHandler)ctor.Invoke(new object[] { handler, unregister }); return(weakHandler.Handler); }
public static EventHandler <TEventArgs> AsWeak <TEventArgs>([NotNull] this EventHandler <TEventArgs> handler, Action <EventHandler <TEventArgs> > unregister) where TEventArgs : EventArgs { Requires.NotNull(handler, nameof(handler)); if (handler.Method.IsStatic) { return(handler); } Type t = typeof(WeakEventHandler <,>).MakeGenericType(handler.Method.DeclaringType, typeof(TEventArgs)); ConstructorInfo ctor = t.GetConstructor(new Type[] { typeof(EventHandler <TEventArgs>), typeof(Action <EventHandler <TEventArgs> >) }); IWeakEventHandler <TEventArgs> weakHandler = (IWeakEventHandler <TEventArgs>)ctor.Invoke(new object[] { handler, unregister }); return(weakHandler.Handler); }
public static EventHandler AsWeak(EventHandler handler, Action <EventHandler> unregister) { Contract.Requires <ArgumentNullException>(handler != null, "handler"); Contract.Ensures(Contract.Result <EventHandler>() != null); if (handler.Method.IsStatic) { return(handler); } Type t = typeof(WeakEventHandler <>).MakeGenericType(handler.Method.DeclaringType); ConstructorInfo ctor = t.GetConstructor(new Type[] { typeof(EventHandler), typeof(Action <EventHandler>) }); IWeakEventHandler weakHandler = (IWeakEventHandler)ctor.Invoke(new object[] { handler, unregister }); return(weakHandler.Handler); }
public static EventHandler <TEventArgs> AsWeak <TEventArgs>(this EventHandler <TEventArgs> handler, Action <EventHandler <TEventArgs> > unregister) where TEventArgs : EventArgs { Contract.Requires <ArgumentNullException>(handler != null, "handler"); Contract.Ensures(Contract.Result <EventHandler <TEventArgs> >() != null); if (handler.Method.IsStatic) { return(handler); } Type t = typeof(WeakEventHandler <,>).MakeGenericType(handler.Method.DeclaringType, typeof(TEventArgs)); ConstructorInfo ctor = t.GetConstructor(new Type[] { typeof(EventHandler <TEventArgs>), typeof(Action <EventHandler <TEventArgs> >) }); IWeakEventHandler <TEventArgs> weakHandler = (IWeakEventHandler <TEventArgs>)ctor.Invoke(new object[] { handler, unregister }); return(weakHandler.Handler); }
/// <summary> /// Finds the weak event handler that has been used to wrap the strong event handler for the supplied delegate /// </summary> /// <typeparam name="TCustomArgs">The type of the event args (derived from EventArgs)</typeparam> /// <param name="sourceEvent">The source event</param> /// <param name="strongEventHandler">The strong event handler to search for</param> /// <returns>The weak event handler if one exists; the strong event handler otherwise</returns> public static EventHandler <TCustomArgs> FindWeak <TCustomArgs>(this Delegate sourceEvent, EventHandler <TCustomArgs> strongEventHandler) where TCustomArgs : EventArgs { // A null source event is legitimate: when unsubscribing from an event, callers do not check if // the event is null. I.e. the following is normal practice. // class Dog #pragma warning disable S125 // Sections of code should not be "commented out" // { // public EventHandler<EventArgs> Barked; // } // var d = new Dog() // d.Barked -= OnBarked; // <-- d.Barked is null at this point. // //if (sourceEvent == null) //{ // throw new ArgumentNullException("sourceHandler"); //} #pragma warning restore S125 // Sections of code should not be "commented out" if (strongEventHandler == null) { throw new ArgumentNullException("strongEventHandler"); } // Look for the weak event handler in the invocation list IWeakEventHandler <TCustomArgs> wehForEh = (sourceEvent == null ? new Delegate[0] : sourceEvent.GetInvocationList()) .Select(ExtractDelegateTarget) .OfType <IWeakEventHandler <TCustomArgs> >() .FirstOrDefault(weh => weh.IsHandlerFor(strongEventHandler)); if (wehForEh != null) { return(wehForEh.HandlerT); } // return the strong event handler if we don't find a wrapped event handler return(strongEventHandler); }
public static EventHandler <TData> MakeWeak <TData>(EventHandler <TData> eventHandler, UnregisterCallback <TData> unregister) { if (eventHandler == null) { throw new ArgumentNullException("eventHandler"); } var methodInfo = eventHandler.GetMethodInfo(); if (methodInfo.IsStatic || eventHandler.Target == null) { throw new ArgumentException("Only instance methods are supported.", "eventHandler"); } Type wehType = typeof(WeakEventHandler <,>).MakeGenericType(typeof(TSender), methodInfo.DeclaringType, typeof(TData)); ConstructorInfo wehConstructor = wehType.GetTypeInfo().GetConstructor(new Type[] { typeof(EventHandler <TData>), typeof(UnregisterCallback <TData>) }); IWeakEventHandler <TData> weh = (IWeakEventHandler <TData>)wehConstructor.Invoke( new object[] { eventHandler, unregister }); return(weh.Handler); }
private static NotifyCollectionChangedEventHandler CreateHandler(IWeakEventHandler <NotifyCollectionChangedEventArgs> weakEventHandler) { return(weakEventHandler.Handle); }
private static EventHandler <DataErrorsChangedEventArgs> CreateHandler(IWeakEventHandler <DataErrorsChangedEventArgs> weakEventHandler) { return(weakEventHandler.Handle); }
private static PropertyChangedEventHandler CreateHandler(IWeakEventHandler <PropertyChangedEventArgs> weakEventHandler) { return(weakEventHandler.Handle); }