ADN Open CIS
Сообщество программистов Autodesk в СНГ

07/02/2015

Использование WeakEventManager с событиями AutoCAD

Недавно мы получили вопрос от разработчика об использовании Менеджера Слабых Событий (WeakEventManager) при работе с событиями AutoCAD. В этой статье мы увидим три разных версии подписки на событие завершение команды (CommandEnded) класса Document. Преимущество использования WeakEventManager в предотвращение утечки памяти, когда на событие подписаны, но они уже не нужны. Но при этом использование WeakEventManager имеет свою цену, так как события теперь доставляются через менеждер событий. Дополнительная цена использования шаблона слабых событий отлично расписана в этой статье Reed Copsey.

Рекомендуется отписываться от событий AutoCAD вручную, но следующие образцы кода должны продемонстрировать использование WeakEventManager в том случае если он вам нужен.

Код - C#: [Выделить]
  1.   public class Commands :
  2.               IExtensionApplication,
  3.               System.Windows.IWeakEventListener
  4.   {
  5.     void IExtensionApplication.Initialize() { }
  6.     void IExtensionApplication.Terminate() { }
  7.  
  8.     #region  Version 1 (Без использования WeakEventManager)
  9.  
  10.     // Version : 1
  11.  
  12.     bool bAdded1 = false;
  13.  
  14.     [CommandMethod("StartMonitor1")]
  15.     public void StartMonitorMethod()
  16.     {
  17.       Document doc = Application.DocumentManager.MdiActiveDocument;
  18.  
  19.       if (bAdded1 == false)
  20.       {
  21.         doc.CommandEnded += new CommandEventHandler(doc_CommandEnded);
  22.         bAdded1 = true;
  23.         doc.Editor.WriteMessage("\nПодписались на событие CommandEnded");
  24.       }
  25.     }
  26.  
  27.     [CommandMethod("EndMonitor1")]
  28.     public void EndMonitorMethod()
  29.     {
  30.       Document doc = Application.DocumentManager.MdiActiveDocument;
  31.       if (bAdded1 == true)
  32.       {
  33.         doc.CommandEnded -= new CommandEventHandler(doc_CommandEnded);
  34.         bAdded1 = false;
  35.         doc.Editor.WriteMessage("\nОтписались от события CommandEnded");
  36.       }
  37.     }
  38.  
  39.     void doc_CommandEnded(object sender, CommandEventArgs e)
  40.     {
  41.       Document doc = Application.DocumentManager.MdiActiveDocument;
  42.       Editor ed = doc.Editor;
  43.       if (bAdded3)
  44.         ed.WriteMessage("\n (Слабое событие) Завершилась команда : {0}",
  45.              e.GlobalCommandName);
  46.       else
  47.         ed.WriteMessage("\n (Событие) Команда завершилась: {0}",
  48.           e.GlobalCommandName);
  49.     }
  50.  
  51.     #endregion
  52.  
  53.     // (Использование WeakEventManager (частная версия) 
  54.  
  55.     #region  Version 2
  56.  
  57.     bool bAdded2 = false;
  58.  
  59.     [CommandMethod("StartMonitor2")]
  60.     public void StartMonitor2Method()
  61.     {
  62.       Document doc = Application.DocumentManager.MdiActiveDocument;
  63.       if (bAdded2 == false)
  64.       {
  65.         CommandEndedEventManager.AddListener(doc, this);
  66.         bAdded2 = true;
  67.         doc.Editor.WriteMessage("\nПодписались на слабое событие CommandEnded");
  68.       }
  69.     }
  70.  
  71.     [CommandMethod("EndMonitor2")]
  72.     public void EndMonitor2Method()
  73.     {
  74.       Document doc = Application.DocumentManager.MdiActiveDocument;
  75.       if (bAdded2 == true)
  76.       {
  77.         CommandEndedEventManager.RemoveListener(doc, this);
  78.         bAdded2 = false;
  79.         doc.Editor.WriteMessage("\nОтписались от слабого события CommandEnded");
  80.       }
  81.     }
  82.  
  83.     bool System.Windows.IWeakEventListener.ReceiveWeakEvent
  84.             (Type managerType, object sender, EventArgs e)
  85.     {
  86.       if (managerType.Equals(typeof(CommandEndedEventManager)))
  87.       {
  88.         Document doc = sender as Document;
  89.         CommandEventArgs ce = e as CommandEventArgs;
  90.  
  91.         Editor ed = doc.Editor;
  92.  
  93.         ed.WriteMessage("\n (Слабое событие) Завершилась команда : {0}",
  94.              ce.GlobalCommandName);
  95.         return true;
  96.       }
  97.       return false;
  98.     }
  99.  
  100.     #endregion
  101.  
  102.     // (Использование общего WeakEventManager в .Net framework 4.5)
  103.  
  104.     #region  Version 3
  105.  
  106.     bool bAdded3 = false;
  107.  
  108.     [CommandMethod("StartMonitor3")]
  109.     public void StartMonitor3Method()
  110.     {
  111.       Document doc = Application.DocumentManager.MdiActiveDocument;
  112.       if (bAdded3 == false)
  113.       {
  114.         System.Windows.WeakEventManager<Document, CommandEventArgs>
  115.            .AddHandler(doc, "CommandEnded", doc_CommandEnded);
  116.         bAdded3 = true;
  117.         doc.Editor.WriteMessage("\nПодписались на слабое событие CommandEnded");
  118.       }
  119.     }
  120.  
  121.     [CommandMethod("EndMonitor3")]
  122.     public void EndMonitor3Method()
  123.     {
  124.       Document doc = Application.DocumentManager.MdiActiveDocument;
  125.       if (bAdded3 == true)
  126.       {
  127.         System.Windows.WeakEventManager
  128.             <Document, CommandEventArgs>
  129.             .RemoveHandler(doc, "CommandEnded", doc_CommandEnded);
  130.         bAdded3 = false;
  131.         doc.Editor.WriteMessage("\nОтписались от слабого события CommandEnded");
  132.       }
  133.     }
  134.  
  135.     #endregion
  136.  
  137.   }
  138.  
  139.   // Для Version 2 
  140.  
  141.   // Использование частной версии WeakEventManager
  142.  
  143.   public class CommandEndedEventManager
  144.               : System.Windows.WeakEventManager
  145.   {
  146.     public static CommandEndedEventManager CurrentManager
  147.     {
  148.       get
  149.       {
  150.         CommandEndedEventManager manager =
  151.           System.Windows.WeakEventManager.GetCurrentManager(
  152.               typeof(CommandEndedEventManager))  as CommandEndedEventManager;
  153.  
  154.         if (manager == null)
  155.         {
  156.           manager = new CommandEndedEventManager();
  157.           System.Windows.WeakEventManager.SetCurrentManager(typeof(CommandEndedEventManager), manager);
  158.         }
  159.         return manager;
  160.       }
  161.     }
  162.  
  163.     public static void AddListener(Document source, System.Windows.IWeakEventListener listener)
  164.     {
  165.       CurrentManager.ProtectedAddListener (source, listener);
  166.     }
  167.     public static void RemoveListener(Document source, System.Windows.IWeakEventListener listener)
  168.     {
  169.       CurrentManager.ProtectedRemoveListener(source, listener);
  170.     }
  171.     protected override void StartListening(object source)
  172.     {
  173.       try
  174.       {
  175.         ((Document)source).CommandEnded += deliver_CommandEnded;
  176.       }
  177.       catch (System.Exception ex)
  178.       {
  179.         Document doc = Application.DocumentManager.MdiActiveDocument;
  180.         Editor ed = doc.Editor;
  181.         ed.WriteMessage(ex.Message);
  182.       }
  183.     }
  184.     void deliver_CommandEnded( object sender, CommandEventArgs e)
  185.     {
  186.       this.DeliverEvent(sender, e);
  187.     }
  188.     protected override void StopListening(object source)
  189.     {
  190.       try
  191.       {
  192.         ((Document)source).CommandEnded -= deliver_CommandEnded;
  193.       }
  194.       catch (System.Exception ex)
  195.       {
  196.         System.Windows.MessageBox.Show(ex.Message);
  197.       }
  198.     }
  199.   }

 

Источник: http://adndevblog.typepad.com/autocad/2015/02/using-weakeventmanager-with-autocad-events.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=1844

Опубликовано 07.02.2015