Использование WeakEventManager с событиями AutoCAD
Недавно мы получили вопрос от разработчика об использовании Менеджера Слабых Событий (WeakEventManager) при работе с событиями AutoCAD. В этой статье мы увидим три разных версии подписки на событие завершение команды (CommandEnded) класса Document. Преимущество использования WeakEventManager в предотвращение утечки памяти, когда на событие подписаны, но они уже не нужны. Но при этом использование WeakEventManager имеет свою цену, так как события теперь доставляются через менеждер событий. Дополнительная цена использования шаблона слабых событий отлично расписана в этой статье Reed Copsey.
Рекомендуется отписываться от событий AutoCAD вручную, но следующие образцы кода должны продемонстрировать использование WeakEventManager в том случае если он вам нужен.
- public class Commands :
- IExtensionApplication,
- System.Windows.IWeakEventListener
- {
- void IExtensionApplication.Initialize() { }
- void IExtensionApplication.Terminate() { }
- #region Version 1 (Без использования WeakEventManager)
- // Version : 1
- bool bAdded1 = false;
- [CommandMethod("StartMonitor1")]
- public void StartMonitorMethod()
- {
- Document doc = Application.DocumentManager.MdiActiveDocument;
- if (bAdded1 == false)
- {
- doc.CommandEnded += new CommandEventHandler(doc_CommandEnded);
- bAdded1 = true;
- doc.Editor.WriteMessage("\nПодписались на событие CommandEnded");
- }
- }
- [CommandMethod("EndMonitor1")]
- public void EndMonitorMethod()
- {
- Document doc = Application.DocumentManager.MdiActiveDocument;
- if (bAdded1 == true)
- {
- doc.CommandEnded -= new CommandEventHandler(doc_CommandEnded);
- bAdded1 = false;
- doc.Editor.WriteMessage("\nОтписались от события CommandEnded");
- }
- }
- void doc_CommandEnded(object sender, CommandEventArgs e)
- {
- Document doc = Application.DocumentManager.MdiActiveDocument;
- Editor ed = doc.Editor;
- if (bAdded3)
- ed.WriteMessage("\n (Слабое событие) Завершилась команда : {0}",
- e.GlobalCommandName);
- else
- ed.WriteMessage("\n (Событие) Команда завершилась: {0}",
- e.GlobalCommandName);
- }
- #endregion
- // (Использование WeakEventManager (частная версия)
- #region Version 2
- bool bAdded2 = false;
- [CommandMethod("StartMonitor2")]
- public void StartMonitor2Method()
- {
- Document doc = Application.DocumentManager.MdiActiveDocument;
- if (bAdded2 == false)
- {
- CommandEndedEventManager.AddListener(doc, this);
- bAdded2 = true;
- doc.Editor.WriteMessage("\nПодписались на слабое событие CommandEnded");
- }
- }
- [CommandMethod("EndMonitor2")]
- public void EndMonitor2Method()
- {
- Document doc = Application.DocumentManager.MdiActiveDocument;
- if (bAdded2 == true)
- {
- CommandEndedEventManager.RemoveListener(doc, this);
- bAdded2 = false;
- doc.Editor.WriteMessage("\nОтписались от слабого события CommandEnded");
- }
- }
- bool System.Windows.IWeakEventListener.ReceiveWeakEvent
- (Type managerType, object sender, EventArgs e)
- {
- if (managerType.Equals(typeof(CommandEndedEventManager)))
- {
- Document doc = sender as Document;
- CommandEventArgs ce = e as CommandEventArgs;
- Editor ed = doc.Editor;
- ed.WriteMessage("\n (Слабое событие) Завершилась команда : {0}",
- ce.GlobalCommandName);
- return true;
- }
- return false;
- }
- #endregion
- // (Использование общего WeakEventManager в .Net framework 4.5)
- #region Version 3
- bool bAdded3 = false;
- [CommandMethod("StartMonitor3")]
- public void StartMonitor3Method()
- {
- Document doc = Application.DocumentManager.MdiActiveDocument;
- if (bAdded3 == false)
- {
- System.Windows.WeakEventManager<Document, CommandEventArgs>
- .AddHandler(doc, "CommandEnded", doc_CommandEnded);
- bAdded3 = true;
- doc.Editor.WriteMessage("\nПодписались на слабое событие CommandEnded");
- }
- }
- [CommandMethod("EndMonitor3")]
- public void EndMonitor3Method()
- {
- Document doc = Application.DocumentManager.MdiActiveDocument;
- if (bAdded3 == true)
- {
- System.Windows.WeakEventManager
- <Document, CommandEventArgs>
- .RemoveHandler(doc, "CommandEnded", doc_CommandEnded);
- bAdded3 = false;
- doc.Editor.WriteMessage("\nОтписались от слабого события CommandEnded");
- }
- }
- #endregion
- }
- // Для Version 2
- // Использование частной версии WeakEventManager
- public class CommandEndedEventManager
- : System.Windows.WeakEventManager
- {
- public static CommandEndedEventManager CurrentManager
- {
- get
- {
- CommandEndedEventManager manager =
- System.Windows.WeakEventManager.GetCurrentManager(
- typeof(CommandEndedEventManager)) as CommandEndedEventManager;
- if (manager == null)
- {
- manager = new CommandEndedEventManager();
- System.Windows.WeakEventManager.SetCurrentManager(typeof(CommandEndedEventManager), manager);
- }
- return manager;
- }
- }
- public static void AddListener(Document source, System.Windows.IWeakEventListener listener)
- {
- CurrentManager.ProtectedAddListener (source, listener);
- }
- public static void RemoveListener(Document source, System.Windows.IWeakEventListener listener)
- {
- CurrentManager.ProtectedRemoveListener(source, listener);
- }
- protected override void StartListening(object source)
- {
- try
- {
- ((Document)source).CommandEnded += deliver_CommandEnded;
- }
- catch (System.Exception ex)
- {
- Document doc = Application.DocumentManager.MdiActiveDocument;
- Editor ed = doc.Editor;
- ed.WriteMessage(ex.Message);
- }
- }
- void deliver_CommandEnded( object sender, CommandEventArgs e)
- {
- this.DeliverEvent(sender, e);
- }
- protected override void StopListening(object source)
- {
- try
- {
- ((Document)source).CommandEnded -= deliver_CommandEnded;
- }
- catch (System.Exception ex)
- {
- System.Windows.MessageBox.Show(ex.Message);
- }
- }
- }
Источник: 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