zoukankan      html  css  js  c++  java
  • Prism中的WeakEventHandlerManager

    View Code
      1 //===================================================================================
      2 // Microsoft patterns & practices
      3 // Composite Application Guidance for Windows Presentation Foundation and Silverlight
      4 //===================================================================================
      5 // Copyright (c) Microsoft Corporation.  All rights reserved.
      6 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
      7 // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
      8 // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
      9 // FITNESS FOR A PARTICULAR PURPOSE.
     10 //===================================================================================
     11 // The example companies, organizations, products, domain names,
     12 // e-mail addresses, logos, people, places, and events depicted
     13 // herein are fictitious.  No association with any real company,
     14 // organization, product, domain name, email address, logo, person,
     15 // places, or events is intended or should be inferred.
     16 //===================================================================================
     17 using System;
     18 using System.Collections.Generic;
     19 using System.Windows.Threading;
     20 using System.Windows;
     21 
     22 namespace Microsoft.Practices.Prism.Commands
     23 {
     24     /// <summary>
     25     /// Handles management and dispatching of EventHandlers in a weak way.
     26     /// </summary>
     27     internal static class WeakEventHandlerManager
     28     {
     29         ///<summary>
     30         /// Invokes the handlers 
     31         ///</summary>
     32         ///<param name="sender"></param>
     33         ///<param name="handlers"></param>
     34         public static void CallWeakReferenceHandlers(object sender, List<WeakReference> handlers)
     35         {
     36             if (handlers != null)
     37             {
     38                 // Take a snapshot of the handlers before we call out to them since the handlers
     39                 // could cause the array to me modified while we are reading it.
     40                 EventHandler[] callees = new EventHandler[handlers.Count];
     41                 int count = 0;
     42 
     43                 //Clean up handlers
     44                 count = CleanupOldHandlers(handlers, callees, count);
     45 
     46                 // Call the handlers that we snapshotted
     47                 for (int i = 0; i < count; i++)
     48                 {
     49                     CallHandler(sender, callees[i]);
     50                 }
     51             }
     52         }
     53 
     54         private static void CallHandler(object sender, EventHandler eventHandler)
     55         {
     56             DispatcherProxy dispatcher = DispatcherProxy.CreateDispatcher();
     57 
     58             if (eventHandler != null)
     59             {
     60                 if (dispatcher != null && !dispatcher.CheckAccess())
     61                 {
     62                     dispatcher.BeginInvoke((Action<object, EventHandler>)CallHandler, sender, eventHandler);
     63                 }
     64                 else
     65                 {
     66                     eventHandler(sender, EventArgs.Empty);
     67                 }
     68             }
     69         }
     70 
     71         /// <summary>
     72         /// Hides the dispatcher mis-match between Silverlight and .Net, largely so code reads a bit easier
     73         /// </summary>
     74         private class DispatcherProxy
     75         {
     76             Dispatcher innerDispatcher;
     77 
     78             private DispatcherProxy(Dispatcher dispatcher)
     79             {
     80                 innerDispatcher = dispatcher;
     81             }
     82 
     83             public static DispatcherProxy CreateDispatcher()
     84             {
     85                 DispatcherProxy proxy = null;
     86 #if SILVERLIGHT
     87                 if (Deployment.Current == null)
     88                     return null;
     89 
     90                 proxy = new DispatcherProxy(Deployment.Current.Dispatcher);
     91 #else
     92                 if (Application.Current == null)
     93                     return null;
     94 
     95                 proxy = new DispatcherProxy(Application.Current.Dispatcher);
     96 #endif
     97                 return proxy;
     98 
     99             }
    100 
    101             public bool CheckAccess()
    102             {
    103                 return innerDispatcher.CheckAccess();
    104             }
    105 
    106             [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Windows.Threading.Dispatcher.#BeginInvoke(System.Delegate,System.Windows.Threading.DispatcherPriority,System.Object[])")]
    107             public DispatcherOperation BeginInvoke(Delegate method, params Object[] args)
    108             {
    109 #if SILVERLIGHT
    110                 return innerDispatcher.BeginInvoke(method, args);
    111 #else
    112                 return innerDispatcher.BeginInvoke(method, DispatcherPriority.Normal, args);
    113 #endif
    114             }
    115         }
    116 
    117         private static int CleanupOldHandlers(List<WeakReference> handlers, EventHandler[] callees, int count)
    118         {
    119             for (int i = handlers.Count - 1; i >= 0; i--)
    120             {
    121                 WeakReference reference = handlers[i];
    122                 EventHandler handler = reference.Target as EventHandler;
    123                 if (handler == null)
    124                 {
    125                     // Clean up old handlers that have been collected
    126                     handlers.RemoveAt(i);
    127                 }
    128                 else
    129                 {
    130                     callees[count] = handler;
    131                     count++;
    132                 }
    133             }
    134             return count;
    135         }
    136 
    137         ///<summary>
    138         /// Adds a handler to the supplied list in a weak way.
    139         ///</summary>
    140         ///<param name="handlers">Existing handler list.  It will be created if null.</param>
    141         ///<param name="handler">Handler to add.</param>
    142         ///<param name="defaultListSize">Default list size.</param>
    143         public static void AddWeakReferenceHandler(ref List<WeakReference> handlers, EventHandler handler, int defaultListSize)
    144         {
    145             if (handlers == null)
    146             {
    147                 handlers = (defaultListSize > 0 ? new List<WeakReference>(defaultListSize) : new List<WeakReference>());
    148             }
    149 
    150             handlers.Add(new WeakReference(handler));
    151         }
    152 
    153         ///<summary>
    154         /// Removes an event handler from the reference list.
    155         ///</summary>
    156         ///<param name="handlers">Handler list to remove reference from.</param>
    157         ///<param name="handler">Handler to remove.</param>
    158         public static void RemoveWeakReferenceHandler(List<WeakReference> handlers, EventHandler handler)
    159         {
    160             if (handlers != null)
    161             {
    162                 for (int i = handlers.Count - 1; i >= 0; i--)
    163                 {
    164                     WeakReference reference = handlers[i];
    165                     EventHandler existingHandler = reference.Target as EventHandler;
    166                     if ((existingHandler == null) || (existingHandler == handler))
    167                     {
    168                         // Clean up old handlers that have been collected
    169                         // in addition to the handler that is to be removed.
    170                         handlers.RemoveAt(i);
    171                     }
    172                 }
    173             }
    174         }
    175     }
    176 }
  • 相关阅读:
    RocketMQ系列(一)基本概念
    怎样实现登录?| Cookie or JWT
    Hotspot GC研发工程师也许漏掉了一块逻辑
    初级Java工程师也能轻松进行JVM调优了
    自动化不知如何参数化(二)?xlrd来帮你解决
    自动化不知如何参数化(一)?xlrd来帮你解决
    SpringCloud系列之API网关(Gateway)服务Zuul
    SpringCloud系列之客户端负载均衡Netflix Ribbon
    SpringCloud系列之使用Feign进行服务调用
    Spring Security系列之极速入门与实践教程
  • 原文地址:https://www.cnblogs.com/easy5weikai/p/2813979.html
Copyright © 2011-2022 走看看