2014-02-24 38 views
1

因此,我正在用C#和WPF構建Office(通過VSTO)的應用程序。我看到WPF應用程序(通過內存分析器)在啓動後從不收集。我要儘可能爲WPF應用程序創建一個新的AppDomain,在AppDomain中啓動它,然後使用,卸載AppDomain,但我仍然有對象 - 並且我的手柄仍在增加尺寸。WPF在VSTO中的應用程序沒有被垃圾收集

有誰知道VSTO和WPF應用程序有什麼奇怪的行爲嗎?我唯一的猜測是,由於某種原因,WPF應用程序加載在Office共享的UI線程上,所以它永遠不會被清理乾淨......

對增加句柄的任何想法?我得到了客戶部署團隊的強烈反對,「增加的句柄不可接受」。

編輯:

讓我明確 - WPF應用程序從功能區啓動,然後他們產生輸出在各自的應用程序,也就是說,如果在Excel中,您將輸入信息,然後將建立一份基於所提供信息的電子表格;如果在PowerPoint中,您將輸入信息(在功能區啓動的WPF應用程序中),它將根據您提供的信息構建幻燈片。

回答

1

我的理解是,VSTO解決方案(至少在Visual Studio 2010中)始終使用default COM shim將VSTO加載項加載到單獨的AppDomain。此隔離保護您的加載項免受其他加載項的任何不穩定性影響。

由於在與VSTO主機應用程序(例如Excel)交互時創建隱藏的運行時可調用包裝器(RCW),您的應用程序的內存使用量是否正在增加?

我的第一個VSTO應用程序一開始依靠Marshal.ReleaseComObject()釋放的RCW,但是,我改變了我的方法如下使用基於這些博客文章:

我現在用這種方法強制GC到

public static class OfficeHelper 
{ 
    /// <summary> 
    /// Forces a GC to release unused run time callable wrappers around COM objects 
    /// </summary> 
    /// <example> 
    /// dynamic rcw; 
    /// try 
    /// { 
    ///  rcw = Globals.ThisWorkbook.ActiveSheet; 
    ///  // do something 
    ///  // ... 
    /// } 
    /// finally 
    /// { 
    ///  rcw = null; 
    ///  OfficeHelper.Cleanup(); 
    /// } 
    /// </example> 
    public static void Cleanup() 
    { 
    System.Diagnostics.Debug.Print("OfficeHelper::Cleanup - GC forced"); 
    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
    System.Diagnostics.Debug.Print("OfficeHelper::Cleanup - GC finished"); 
    } 

}

到目前爲止,這種方法已經在我的應用程序運作良好,和GC時代已經比我預期的要快。

+0

我實際上在每個應用程序「結束」之後都有這兩行......但我仍然看到句柄/內存等的增加。記憶不是一個大問題,但手柄似乎是。 – Locke

+0

來自[微軟的周冀](http://social.msdn.microsoft.com/Forums/vstudio/en-US/086b7b17-f4d2-4f84-aeb3-68e9ffdbf9a8/what-are-the-silar- geandanddifferences -between-shared-addin-and-vsto-applicationlevel-addin?forum = vsto):> Visual Studio Tools for Office創建一個新的AppDomain來加載每個VSTO加載項。所以,它不會互相影響。程序員不需要擔心「Outlook不會關閉」問題。當VSTO加載項關閉時,AppDomain將被卸載,並且它將回收程序員在應用程序中分配的資源。 –

+0

如果我們從創建幻燈片/輸出的VSTO功能區啓動應用程序,該怎麼辦?即您單擊VSTO功能區上的按鈕,然後啓動一個應用程序,該應用程序需要一些信息並自動創建帶有互操作類型的幻燈片? – Locke