2012-10-01 3 views
1

Предположим, что у меня есть класс, называемый классом viewmode mvvm. Затем для этого vm созданы обработчики событий. то он может использоваться многими другими с другой ситуацией.как обнаружить обработчик событий и отпустить его?

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

Какой общий способ сделать это из myvm, например, у меня может не быть исходного кода myvm?

+0

Что вы пытаетесь освободить, обработчики событий или myvm? – CrazyCasta

ответ

2

События разработаны таким образом, что код вне класса, который их объявил, не может получить доступ к основному делегату. Так, например, в соответствии с разделом «10.8 События» в C# Language specification (курсив):

В операции вида х + = у или х - = у, когда х является событием и ссылка принимает за пределами типа, который содержит объявление x, результат операции имеет тип void (как , противоположный типу x, со значением x после назначения ). Это правило запрещает внешний код косвенно , рассматривая базовый делегат события.

Таким образом, выяснение того, что подписано на мероприятие вне класса, может быть, в лучшем случае, «работать».

Если у вас есть доступ к источнику класса, содержащего событие, и вы хотите, чтобы следить за делегатов подключили к event, осуществлять add и remove ключевое слово в определении событий и manually keep track of them in a Dictionary.

0

Если я вас правильно понимаю. Этот класс обертывает неизвестный класс myvm, который я использую SocketAsyncEventArgs для иллюстрации, потому что, очевидно, у нас нет исходного кода для класса SocketAsyncEventArgs.

И я завернул завершенное событие класса SocketAsyncEventArgs. Когда это событие будет запущено, будет запущен _instance_Completed, тогда будет запущено событие _myvm. Итак, что нам нужно сделать, это подписаться/отказаться от подписки на событие _myvm.

Затем я оставляю событие для подписки/отмены подписки на событие _myvm, как подписка/отмена подписки, делегаты хранятся в списке, поэтому вы можете очистить , вызвав метод ClearEvents().

Надеюсь, это поможет.

public class WrapperClass 
    { 
     private EventHandler<SocketAsyncEventArgs> _myEvent; 
     private SocketAsyncEventArgs _myvm; 
     private List<Delegate> delegates; 

     public WrapperClass() 
     { 
      delegates = new List<Delegate>(); 
     } 

     public void SetInstance(SocketAsyncEventArgs myvm) 
     { 
      _myvm = myvm; 
      _myvm.Completed += new EventHandler<SocketAsyncEventArgs>(_instance_Completed); 
     } 

     private void _instance_Completed(object sender, SocketAsyncEventArgs e) 
     { 
      if (_myEvent != null) 
      { 
       _myEvent(sender, e); 
      } 
     } 

     public event EventHandler<SocketAsyncEventArgs> myEvent 
     { 
      add 
      { 
       delegates.Add(value); 
       _myEvent = (EventHandler<SocketAsyncEventArgs>)Delegate.Combine(_myEvent, value); 
      } 
      remove 
      { 
       delegates.Remove(value); 
       _myEvent = (EventHandler<SocketAsyncEventArgs>)Delegate.Remove(_myEvent, value); 
      } 
     } 

     public void ClearEvents() 
     { 
      foreach (var d in delegates) 
      { 
      _myEvent = (EventHandler<SocketAsyncEventArgs>)Delegate.Remove(_myEvent, d); 
      } 
     } 
    } 
Смежные вопросы