Setting an Event to Null

2019-03-15 13:36发布

问题:

I have a code like this:

public class SomeClass
{
    int _processProgress;
    public int ProcessProgress 
    { 
        get { return _processProgress; } 
        set 
        { 
            _processProgress = value; 
            if (ProcessProgressChanged != null) 
                ProcessProgressChanged(value);
        } 
    }

    public delegate void ProcessProgressChangedEventHandler(int progressPercentage);
    public event ProcessProgressChangedEventHandler ProcessProgressChanged;

    public void ClearProcessProgressChangedEvent()
    {
        this.ProcessProgressChanged = null;
    }
}

Will it unsubscribe all method in the ProcessProgressChanged event when I call the ClearProcessProgressChangedEvent() method?

My code is in C#, framework 4, build in VS2010 Pro, project is in Winforms.

Please help. Thanks in advance.

回答1:

Well, it'll effectively clear the list of subscribers, yes (by setting the underlying delegate field to null) - so that the next time ProcessProgress is set, no handlers will be called. It's not really setting the event to null - it's setting the underlying field to null. It's just that the C# compiler is creating both an event (a subscribe/unsubscribe pair of methods) and a field (to store the handlers) using a single declaration.

You may find my article about events and delegates useful.

Note that your event-raising code currently isn't thread-safe. I don't know whether it needs to be or not, but you might want to consider using:

set 
{ 
    _processProgress = value; 
    var handlers = ProcessProgressChanged;
    if (handlers != null) 
    {
        handlers(value);
    }
}

That way you won't get a NullReferenceException if the last handler is unsubscribed after the nullity check but before the invocation.



回答2:

Yes, it will unsubscribe everyone from the event. There is a (bit indirect IMHO) reference to this here:

When all subscribers have unsubscribed from an event, the event instance in the publisher class is set to null.