WPF正确处理视图和视图模型

时间:2012-11-01 10:36:53

标签: c# wpf mvvm

我编写了一个Outlook加载项(OL2010)。它在功能区栏上有一个菜单,上面有各种图标,可以打开新窗口(希望不是太深入;))。下面是其中一个图标Click处理程序的示例。

public void OnViewMyTracksClick(Office.IRibbonControl control)
{
    try {
    MyTracksViewModel viewModel = new MyTracksViewModel();
    MyTracksView view = new MyTracksView();
    view.DataContext = viewModel;
    view.Show();
    }
    catch (Exception ex)
    {
        Log.Error("xxxxx", "Error on button click: " + ex.Message + Environment.NewLine + ex.InnerException);
    }
}

在Outlook中,如果我单击按钮打开此视图,我会看到Outlook.exe的内存使用量增加10mb(窗口及其附带的数据)。当我关闭视图时,没有回收任何内存。如果我再次单击该按钮,则会添加另一个10mb,并且当我关闭视图时,再次没有释放。

我认为这是因为我每次都在创建一个新的视图模型,所以我添加了一些代码来检查它是否已经实例化(视图和视图模型现在在类级别注册,而不是在方法中注册,所以我不是每次都创建一个新的) - _allTracksVMAllTracksViewModel的实例化。 _allTracksV是视图。

public void OnViewAllTracksClick(Office.IRibbonControl control)
{
    try {
        if (_allTracksVM == null)
        {
            _allTracksVM = new AllTracksViewModel();

        }
        _allTracksV = new AllTracksView();
        _allTracksV.DataContext = _allTracksVM;
        _allTracksV.Show();
    }
    catch (Exception ex)
    {
        Log.Error("xxxxx", "Error on button click: " + ex.Message + Environment.NewLine + ex.InnerException);
    }
}

这似乎没有任何区别。然后我添加了EventHandler,当视图关闭时会触发:

_allTracksV.Closing += new System.ComponentModel.CancelEventHandler(this.view_RequestClose);

这会将两个对象设置为null(你可能会说我现在正抓住吸管):

void view_RequestClose(object sender, EventArgs e)
{
    _allTracksVM = null;
    _allTracksV = null;
}

内存仍然分配。如何正确处理对象(或者我应该以不同的方式实例化它们),这样每次打开它们时都不会消耗另一块内存?

由于

米克

1 个答案:

答案 0 :(得分:1)

检查VM是否为空是一个好主意,但是通过在关闭处理程序中将其设置为null,它变得无用:) 您可以尝试使视图成为包含类中的字段而不是局部变量。这样,您不需要每次都创建新视图。

至于内存使用情况,在我看来你做得对。由于GC仅在必要时收集,因此需要一些时间直到内存消耗下降。