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);
        }
示例#2
0
        /// <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);
        }
示例#3
0
        /// <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);
        }
示例#4
0
        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 });
                }
            }
示例#6
0
        /// <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();
        }
示例#8
0
        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);
        }
示例#9
0
        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);
        }
示例#12
0
        /// <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);
        }
示例#13
0
文件: Events.cs 项目: rjamesnw/CoreXT
            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);
 }