KentZhou
KentZhou

Reputation: 25553

how to detect event handler and released it?

Suppose I have a class say a viewmode class mvvm. Then there are some event handlers created for this vm. then it could be used by many others with different situation.

So if I have an instance of myvm, I want to detect if there is any event handler hooked up and want to release it for memory issue.

What's the generic way to do this out of myvm, for example, I may not have the source code of myvm?

Upvotes: 1

Views: 844

Answers (2)

Larry
Larry

Reputation: 2252

If I understand you correctly. This class wraps the unknown myvm class which I use SocketAsyncEventArgs to illustrate, cos obviously we don't have the source code for SocketAsyncEventArgs class.

And I wrapped the Completed event of SocketAsyncEventArgs class. When that event is triggered, _instance_Completed will be fired, then _myvm event will be fired. So what we need to do is subscribe/unsubscribe _myvm event.

Then I leave an event for people to subscribe/unsubscribe _myvm event, as subscribing/unsubscribing, the delegates are stored into a List therefore you can clear the by call the ClearEvents() method.

Hope it will help.

    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);
            }
        }
    }

Upvotes: 0

akton
akton

Reputation: 14376

Events are designed such that code outside the class that declared them cannot get access to the underlying delegate. For example, according to Section "10.8 Events" in the C# Language specification (emphasis mine):

In an operation of the form x += y or x -= y, when x is an event and the reference takes place outside the type that contains the declaration of x, the result of the operation has type void (as opposed to having the type of x, with the value of x after the assignment). This rule prohibits external code from indirectly examining the underlying delegate of an event.

Therefore, finding out what is subscribed to the event outside the class may be, at best, a "work around".

If you have access to the source of the class containing the event and you want to keep track of delegates hooked up to an event, implement the add and remove keyword in the event definition and manually keep track of them in a Dictionary.

Upvotes: 2

Related Questions