.NET object events and dispose / GC

后端 未结 7 2085
孤城傲影
孤城傲影 2020-12-09 12:28

EDIT: After Joel Coehoorns excellent answer, I understand that I need to be more specific, so I modified my code to be closer to thing I\'m trying to unders

7条回答
  •  旧时难觅i
    2020-12-09 13:18

    You don't need to unhook event handlers when disposing of an object, although you may want to. By that I mean that the GC will clean up event handlers just fine without any intervention on your part, however depending on the scenario you may want to remove those event handlers before the GC does in order to prevent the handler being called when you weren't expecting it.

    In your example I think you have your roles reversed - class A shouldn't really be unsubscribing event handlers added by others and has no real need to remove event handlers eiether, as it can instead just stop raising those events!

    Suppose however that the situation is reversed

    class A
    {
       public EventHandler EventHappened;
    }
    
    class B : IDisposable
    {
        A _a;
        private bool disposed;
    
        public B(A a)
        {
            _a = a;
            a.EventHappened += this.HandleEvent;
        }
    
        public void Dispose(bool disposing)
        {
            // As an aside - if disposing is false then we are being called during 
            // finalization and so cannot safely reference _a as it may have already 
            // been GCd
            // In this situation we dont to remove the handler anyway as its about
            // to be cleaned up by the GC anyway
            if (disposing)
            {
                // You may wish to unsubscribe from events here
                _a.EventHappened -= this.HandleEvent;
                disposed = true;
            }
        }
    
        public void HandleEvent(object sender, EventArgs args)
        {
            if (disposed)
            {
                throw new ObjectDisposedException();
            }
        }
     }
    

    If its possible for A to continue raising events even after B has been disposed, and the event handler for B could do something that may cause either an exception or some other unexpected behaviour if B is disposed then its probably a good idea to unsubscribe from this event first.

提交回复
热议问题