What best practices for cleaning up event handler references?

后端 未结 6 1639
一个人的身影
一个人的身影 2020-12-04 15:52

Often I find myself writing code like this:

        if (Session != null)
        {
            Session.KillAllProcesses();
            Session.AllUnitsReady          


        
6条回答
  •  日久生厌
    2020-12-04 16:31

    Implementing IDisposable has two advantages over the manual method:

    1. It's standard and the compiler treats it specially. Meaning that everybody that reads your code understand what it's about the minute they see IDisposable being implemented.
    2. .NET C# and VB provide special constructs for working with IDisposable via the using statement.

    Still, I doubt whether this is useful in your scenario. To safely dispose of an object, it needs to be disposed of in the finally-block inside a try/catch. In the case you seem to describe, it may require that either Session takes care of this, or the code calling the Session, upon deletion of the object (i.e., at the end of its scope: in the finally block). If so, the Session must implement IDisposable too, which follows the common concept. Inside the IDisposable.Dispose method, it loops through all its members that are disposable and disposes of them.

    Edit

    Your latest comment makes me rethink my answer and try to connect a few dots. You want to make sure Session is disposable by the GC. If the references to the delegates are from inside the same class, it is not necessary at all to unsubscribe them. If they are from another class, you need to unsubscribe them. Looking at the code above, you seem to write that code block in any class that uses Session and clean it up at some point in the process.

    If Session needs to be freed, there's a more direct way were calling class needs not be responsible for correct handling the unsubscribe process. Simply loop all events using trivial reflection and set all to null (you can consider alternative approaches to reach the same effect).

    Because you ask for "best practices", you should combine this method with IDisposable and implement the loop inside IDisposable.Dispose(). Before you enter this loop, you call one more event: Disposing, which listeners can use if they need to clean up anything themselves. When using IDisposable, be aware of its caveats, of which this briefly described pattern is a common solution.

提交回复
热议问题