Как определить обработчик события и освободить его?

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

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

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

2 ответа

События разработаны таким образом, что код за пределами объявившего их класса не может получить доступ к базовому делегату. Например, в соответствии с разделом "10.8 События" в спецификации языка C# (выделено мое):

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

Поэтому выяснение того, что подписано на мероприятие вне класса, может быть, в лучшем случае, "обходным путем".

Если у вас есть доступ к источнику класса, содержащего событие, и вы хотите отслеживать делегатов, подключенных к событию, внедрите ключевое слово add и remove в определении события и вручную отследите их в Словаре.

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

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

Затем я оставляю событие для людей, чтобы подписаться / отписаться от события _myvm, так как при подписке / отписке делегаты сохраняются в List, поэтому вы можете очистить вызов с помощью метода 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);
            }
        }
    }
Другие вопросы по тегам