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

02/10/2015

Не могу удалить обработчик события в .NET

Когда моё .NET-приложение загружается, оно подписывается на событие DocumentToBeDestroyed и нормально работает.

Когда позднее я пытаюсь отписаться от обработки этого события, у меня это не получается и мой обработчик продолжает  вызываться.

Вот мой код::

Код - VB.NET: [Выделить]
  1. Imports Autodesk.AutoCAD.Runtime
  2. Imports Autodesk.AutoCAD.ApplicationServices
  3.  
  4. Public Class Commands
  5.   Implements IExtensionApplication
  6.  
  7.   Public Sub Initialize() Implements IExtensionApplication.Initialize
  8.     AddHandler _
  9.       Application.DocumentManager.DocumentToBeDestroyed, _
  10.       AddressOf docBeginDocClose
  11.   End Sub
  12.  
  13.   Public Sub Terminate() Implements IExtensionApplication.Terminate
  14.   End Sub
  15.  
  16.   Public Sub docBeginDocClose( _
  17.     ByVal senderObj As Object, _
  18.     ByVal docColDocActEvtArgs As DocumentCollectionEventArgs)
  19.  
  20.     System.Diagnostics.Debug.Print("В docBeginDocClose")
  21.   End Sub
  22.  
  23.   <CommandMethod("StopEvent")> _
  24.   Public Sub StopEvents()
  25.     Try
  26.       RemoveHandler _
  27.         Application.DocumentManager.DocumentToBeDestroyed, _
  28.         AddressOf docBeginDocClose
  29.     Catch ex As Exception
  30.       MsgBox("Ошибка: " & ex.Message)
  31.     End Try
  32.   End Sub
  33.  
  34. End Class

Решение:

AutoCAD создаёт экземпляр класса, который  содержит метод Initialize(). Если функция команды – это функция экземпляра класса (т.е. не имеет атрибутов static/shared), в этом случае AutoCAD создаёт новые экземпляры этого класса, содержащего эту функцию, для каждого из открытых документов. Если обработчик события тоже функция экземпляра класса, тогда вы получаете её экземпляр соответствующий тому экземпляру класса, что и обработчик вызванной команды.

Таким образом вы подключаетесь к событию внутри Initialize() или команды, и пытаетесь потом отключить другой экземпляр функции-обработчика, который не подписан на событие, а тот который подписан на событие при этом не отписывается.

Вот поэтому обработчик события продолжает вызываться даже если мы пытаемся его отписать от события.

Таким образом простейшим решением является указать функцию обработчик как статическую (static (C#) / Shared (VB.NET)):

Код - VB.NET: [Выделить]
  1. Public Shared Sub docBeginDocClose( _
  2.   ByVal senderObj As Object, _
  3.   ByVal docColDocActEvtArgs As DocumentCollectionEventArgs)
  4.  
  5.   System.Diagnostics.Debug.Print("В docBeginDocClose")
  6. End Sub

 

Источник: http://adndevblog.typepad.com/autocad/2012/07/cannot-remove-net-event-handler.html

Автор перевода: Александр Ривилис

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

Опубликовано 02.10.2015
Отредактировано 02.10.2015 в 23:12:21