예제 #1
0
        /// <summary>
        /// Adds a weak event handler info.
        /// </summary>
        /// <param name="weakHandlerInfos">The target weak event handler info collection.</param>
        /// <param name="target">The target instance if the event handler is a instance method; otherwise null.</param>
        /// <param name="methodInfo">The event handler method info.</param>
        /// <returns>A new weak event handler info collection.</returns>
        public static IEnumerable <WeakEventHandlerInfo> Add(this IEnumerable <WeakEventHandlerInfo> weakHandlerInfos, object target, MethodInfo methodInfo)
        {
            if (weakHandlerInfos == null)
            {
                throw new ArgumentNullException(nameof(weakHandlerInfos));
            }

            if (methodInfo == null)
            {
                throw new ArgumentNullException(nameof(methodInfo));
            }

            var newWeakHandlerInfos = new WeakEventHandlerInfo[weakHandlerInfos.Count() + 1];

            // Copies existing event handler infos.
            int index = 0;

            foreach (var weakHandlerInfo in weakHandlerInfos)
            {
                newWeakHandlerInfos[index++] = weakHandlerInfo;
            }

            // Copies the new event handler info.
            newWeakHandlerInfos[index] = new WeakEventHandlerInfo(target, methodInfo);

            // Returns the weak event handler info collection.
            return(newWeakHandlerInfos);
        }
예제 #2
0
        /// <summary>
        /// Removes a weak event handler info.
        /// </summary>
        /// <param name="weakHandlerInfos">The target weak event handler info collection.</param>
        /// <param name="target">The target instance if the event handler is a instance method; otherwise null.</param>
        /// <param name="methodInfo">The event handler method info.</param>
        /// <returns>A new weak event handler info collection if the event handler info is removed; otherwise the target weak event handler info collection.</returns>
        public static IEnumerable <WeakEventHandlerInfo> Remove(this IEnumerable <WeakEventHandlerInfo> weakHandlerInfos, object target, MethodInfo methodInfo)
        {
            if (weakHandlerInfos == null)
            {
                throw new ArgumentNullException(nameof(weakHandlerInfos));
            }

            if (methodInfo == null)
            {
                throw new ArgumentNullException(nameof(methodInfo));
            }

            // Finds the weak event handler info to delete.
            var weakHandlerInfoToDelete = weakHandlerInfos.FirstOrDefault
                                          (
                weakHandlerInfo =>
            {
                return(weakHandlerInfo.WeakTarget.Target == target &&
                       weakHandlerInfo.MethodInfo == methodInfo);
            }
                                          );

            // If there is no weak event handler info to delete...
            if (weakHandlerInfoToDelete == null)
            {
                return(weakHandlerInfos);
            }

            var newWeakHandlerInfos = new WeakEventHandlerInfo[weakHandlerInfos.Count() - 1];
            int index = 0;

            foreach (var weakHandlerInfo in weakHandlerInfos)
            {
                // Skips the weak event handler info to delete.
                if (weakHandlerInfo == weakHandlerInfoToDelete)
                {
                    continue;
                }

                newWeakHandlerInfos[index++] = weakHandlerInfo;
            }

            // Returns the weak event handler info collection.
            return(newWeakHandlerInfos);
        }
예제 #3
0
        /// <summary>
        /// Cleans up event handlers that the target objects are garbage collected.
        /// </summary>
        /// <param name="weakHandlerInfos">The target weak event handler info collection.</param>
        /// <param name="sender">The event sender.</param>
        /// <param name="args">The event arguments.</param>
        /// <param name="invokeHandler">If this parameter is true, alive event handlers are invoked.</param>
        /// <returns>A new weak event handler info collection if garbage collected event handler infos are removed; otherwise the target weak event handler info collection.</returns>
        public static IEnumerable <WeakEventHandlerInfo> Cleanup(this IEnumerable <WeakEventHandlerInfo> weakHandlerInfos, object sender, object args, bool invokeHandler)
        {
            if (weakHandlerInfos == null)
            {
                throw new ArgumentNullException(nameof(weakHandlerInfos));
            }

            List <WeakEventHandlerInfo> weakHandlerInfosToDelete = null;

            // For each weak handler info...
            foreach (var weakHandlerInfo in weakHandlerInfos)
            {
                // If the event handler is a static method...
                if (weakHandlerInfo.MethodInfo.IsStatic)
                {
                    // Calls the event handler.
                    if (invokeHandler)
                    {
                        weakHandlerInfo.MethodInfo.Invoke(null, new object[] { sender, args });
                    }
                }
                else
                {
                    // Gets the strong reference.
                    object target = weakHandlerInfo.WeakTarget.Target;

                    // If it is garbage collected..
                    if (target == null)
                    {
                        if (weakHandlerInfosToDelete == null)
                        {
                            weakHandlerInfosToDelete = new List <WeakEventHandlerInfo>();
                        }

                        // Collects the garbage collected event handler info.
                        weakHandlerInfosToDelete.Add(weakHandlerInfo);
                        continue;
                    }

                    // Calls the event handler.
                    if (invokeHandler)
                    {
                        weakHandlerInfo.MethodInfo.Invoke(target, new object[] { sender, args });
                    }
                }
            }

            // If no event handler info is garbage collected..
            if (weakHandlerInfosToDelete == null)
            {
                return(weakHandlerInfos);
            }

            // If all event handlers are garbage collected..
            int weakHandlerInfoCount = weakHandlerInfos.Count();

            if (weakHandlerInfosToDelete.Count == weakHandlerInfoCount)
            {
                return(Enumerable.Empty <WeakEventHandlerInfo>());
            }

            var newWeakHandlerInfos = new WeakEventHandlerInfo[weakHandlerInfoCount - weakHandlerInfosToDelete.Count];
            int index = 0;

            foreach (var weakHandlerInfo in weakHandlerInfos)
            {
                // Skips the event handler info garbage collected
                if (weakHandlerInfosToDelete.Contains(weakHandlerInfo))
                {
                    continue;
                }

                newWeakHandlerInfos[index++] = weakHandlerInfo;
            }

            // Returns the weak event handler info collection.
            return(newWeakHandlerInfos);
        }