In MVVM, does hooking a model item's event in

2019-04-16 05:30发布

问题:

Trying to track down some memory leaks in our WPF/MVVM app and something occurred to me...

If you listen to ModelItem events in its associated ViewModel with an instance-specific handler, doesn’t that make the ViewModelItem hang around as long as the ModelItem still exists?

Consider this case...

public class ItemViewModel
{
    public ItemViewModel(ModelItem item)
    {
        this.Item = item;
        item.SomeEvent += ItemSomeEventHandler
    }

    Public ModelItem Item{ get; private set; }

    // Note: This is a handler on this instance, not a shared handler
    Private void ItemSomeEventHandler(object s, EventArgs e)
    {
        Console.WriteLine(“The model changed!”);
    }
}

If this does cause a leak, how/where do you unhook it? You can't do it in 'Dispose' since that won't be called if something still has a reference to it, which it looks like it does: the model item.

Would the proper place be to implement Dispose in the control where this ViewModel is used, then trickle down an event-unhook routine there? Seems a bit treacherous to rely on something external to make sure you clean up your own internal, but short of going to an EventManager architecture, I'm not sure what to do here.

回答1:

Yes it will cause a leak.. or more specifically the ItemViewModel will not be collected when the view is no longer displayed since the ModelItem holds a reference to the ItemViewModel

You could implement Dispose and unhook the eventhandler which is perfectly valid if you can control the lifecycle of the ViewModel. The question is what component is creating the ItemViewModel? If it is another view model then you can delegate the dispose to that or if the view creates the view model then you can have the call the Dispose method.

However if you use like the MVVMLight toolkit then you can use its ICleanup interface instead or something similar. Check this other answer out for more info.



回答2:

Why not use WeakEvent / DelegateCommands?

They implement weak references to delegates that does not need deterministic detatchment.