2012-11-01 30 views
1

我編寫了一個Outlook加載項(OL2010)。它在功能區欄上有一個菜單,帶有各種圖標,可以打開新窗口來執行操作(希望不要太深入;))。下面是一個圖標Click處理程序的示例。WPF正確處理視圖和視圖模型

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,並且當我關閉視圖時再次沒有任何內容被釋放。

我認爲這是因爲我每次都創建一個新的viewmodel,所以我添加了一些代碼來檢查它是否已經實例化(view和viewmodel現在在類級別註冊,而不是在方法內註冊,所以我不會每次創建一個新的) - _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); 

這種設兩個對象爲空(你可能會說我在抓救命稻草在這一點上):

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

內存仍然分配。我如何正確地處理對象(或者我應該以不同的方式實例化它們),以便每次打開時都不會消耗另一塊內存?

感謝

米克

回答

1

檢查VM爲空是個好主意,但在收盤處理程序將其設置爲null,則形同虛設:) 你可以試着讓視野在包含類中而不是局部變量中。這樣你就不需要每次都創建一個新的視圖。

至於內存使用情況,在我看來,你做對了。由於GC只在必要時收集,因此需要一段時間才能減少存儲空間。

+0

感謝您的回覆。在關閉處理程序中擺脫了null事物。我希望關閉視圖也會處理它(至少最終),但似乎並不是這樣。我的Outlook最初運行時間大約爲100MB。我可以繼續打開和關閉窗口,直到Outlook使用超過500MB。現在肯定只有一個視圖模型的實例,所以我沒有受過教育的猜測是視圖掛在消費內存上。不知道多少次垃圾收集應該發生,但2小時沒有區別。 – MJM

+0

您是否嘗試將視圖本身變成字段?所以你不必每次都創建一個新的視圖,只是顯示和隱藏它? – MrEdge

+0

是的,這就是我最終做的事情,似乎有一個合理的差異。內存仍然上升,但速度相當慢,現在似乎只發生在一個視圖(嵌入在預覽窗口中顯示的元素主機中)。可能有一個暫停的臨時結果集。感謝您的建議。 – MJM