(Note also that C # does not have destructors. 1 it has finalizers. These are very different things and should not be confused.)
The "problem" is on this line:
publisher.SomeEvent += new EventHandler(publisher_SomeEvent);
This creates a delegate that targets the publisher_SomeEvent() method of the specific instance of the object, and adds this delegate to the call list for the publisher.SomeEvent event. This delegate object refers to the target, and this prevents the collection of the object! (This is good - if you accept a delegate to a method for a specific object, then you do not want this object to be assembled until the delegate no longer refers.)
This is technically not a problem at all, but rather, objects that support the runtime are still referenced.
To illustrate this, this is a chain of links:
SomePublisher -+-> EventHandler --> SomeSubscriber | +-> EventHandler --> SomeSubscriber | +-> (Eight more...)
You need to do one of two things before calling GC.Collect() :
- Unsubscribe from an event before releasing each
SomePublisher object. This will make both the EventHandler delegation instances and the SomeSubscriber instances to which they refer suitable for collection. - Set
publisher = null; . This will make the entire graph of the object suitable for collection.
In both cases, this will release all references to SomeSubscriber objects.
1 Note that the C # specification calls these blocks of code "destructors", but it is a terrible name. Those familiar with garbage-collected languages ββwill be confused by it, since βfinalizerβ is a common term for code that is called by the garbage collector when an object is no longer available. C ++ developers, in particular, expect the destructor to be executed at another time. So yes, C # has something called a destructor, but it is not a destructor. (Saying something fails!)
source share