Is it possible to replace the entire standard event handler with WeakEventManager or its varian?

The standard event handler (with the + = operator ) is one of the reasons for the memory leak (if it is not canceled / deleted (with - = operator)).
Microsoft solved it with WeakEventManager and its inheritance like: PropertyChangedEventManager, CollectionChangedEventManager, CurrentChangedEventManager, ErrorsChangedEventManager , etc.

Simple code example with memory leak:

public class EventCaller
{
    public static event EventHandler MyEvent;

    public static void Call()
    {
        var handler = MyEvent;
        if (handler != null)
        {
            handler(null, EventArgs.Empty);
            Debug.WriteLine("=============");
        }
    }
}

public class A
{
    string myText;

    public A(string text)
    {
        myText = text;
        EventCaller.MyEvent += OnCall;

        // Use code below and comment out code above to avoid memory leakage.
        // System.Windows.WeakEventManager<EventCaller, EventArgs>.AddHandler(null, "MyEvent", OnCall);  
    }

    void OnCall(object sender, EventArgs e)
    {
        Debug.WriteLine(myText);
    }

    ~A()
    {
        Debug.WriteLine(myText + " destructor");
    }
}

void Main()
{
    var a = new A("A");
    var b = new A("B");
    EventCaller.Call();
    a = null;
    GC.Collect();
    EventCaller.Call();
}

      

Output:

a
B
+++++++

B
+++++++

We can see that the destructor will not be called. But if we change (by commenting out the unused code) from:

    EventCaller.MyEvent += OnCall;

      

to

    System.Windows.WeakEventManager<EventCaller, EventArgs>.AddHandler(null, "MyEvent", OnCall);  

      

And the output is:

a
B
+++++++
B
+++++++
Destructor
B destructor

After a nulled, its event handler will no longer be called.
A and B will be removed after they are no longer used without the = = operator.

1. Can I safely replace the whole + = operator with System.Windows.WeakEventManager, to avoid memory leaks due to probably not logging events and saving code, shouldn't I implement IDisposable?

2. If it is not entirely safe, what should I consider or notice?

+3


source to share


2 answers


Is it safe to replace the entire + = operator with System.Windows.WeakEventManager

, to avoid a memory leak due to probably not registering an event and saving code, shouldn't IDisposable be implemented?

You can? Probably. You should? Probably no. If you have a strong reference to an event handler, you would rather unsubscribe if the event publisher lives longer than the subscriber, rather than replacing the strong reference with a weak event. There are side effects of using weak events. One of them is performance. Another is the semantic difference. You can refer to the following question and answers about why the event implementation in the .NET Framework does not use the default weak event pattern:



Why isn't the C # event implementation the default for the weak event pattern?

Of course, there are certain scenarios where you should use the weak event pattern. One such scenario is data binding in WPF, where the original object is completely independent of the listener object. But that doesn't mean that you should always use the weak event pattern. And that also doesn't mean that you should stop worrying about recycling subscriptions in your apps.

+3


source


1) I would not take saving code as an argument to use the WeakEventManager instead of implementing IDisposable.

2) In the case of a weak event pattern, event handling will continue until the listener is collected by the garbage collector. Failure to execute the listener does not immediately stop processing events because the strong referenced event handler is not explicitly registered in the Dispose template.

3) See Microsoft documentation regarding Weak Event Patterns



The weak event pattern can be used whenever a listener needs to register for an event, but the listener does not explicitly know when to unregister. The weak event pattern can also be used whenever the lifetime of the source object exceeds the useful lifetime of the listener. (In this case, the utility is up to you.)

If you clearly know when to unregister the listener, I would prefer standard events and implement the Dispose pattern. From the point of view of event handlers, explicit fault tolerance has the advantage that event processing stops immediately while the weak event schema continues to process events (which can also be CPU and memory consumption) until the listener is collected by the garbage collector.

+2


source







All Articles