3

我编写了一个 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;
}

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

谢谢

米克

4

1 回答 1

0

Checking the VM for Null was a good idea but by setting it to null in the close handler, it is rendered useless :) You could try to make the view a field in the containing class rather than a local variable. That way you don't need to create a new view each time.

As for the memory usage, it seems to me that you're doing it right. Since the GC only collects when necessary, it will take some time until the memoryusage declines.

于 2012-11-01T11:50:34.610 回答