2008-11-04 71 views
8

我有一個可以最小化到系統托盤的WinForms應用程序(我使用VB)。我使用了使用NotifyIcon並使用Form_Resize事件播放的多篇文章中描述的「hackish」方法。.NET最小化到托盤和最小化所需資源

這一切在美學上都很好,但所使用的資源和內存不受影響。我希望能夠最小化系統托盤時的資源,就像Visual Studio一樣。如果您在Visual Studio中進行編碼,內存使用量可能會增加(取決於項目大小)到500 MB以上,但是當將Visual Studio最小化到任務欄時,內存大幅減少到(我所假設的)最小量。

有沒有人有任何線索如何做到這一點?

下面是對應用程序的簡短描述,如果有人發現它相關:我有一個窗體窗體,其中包含一個ListView,其中包含我IT部門的工作訂單。該應用程序有一個「偵聽器」,用於通知何時提交新的工單。所以,當應用程序在系統托盤中運行時,我所做的只是將ListView中的項數與每隔幾分鐘SQL表中的行數進行比較。

編輯:更具體地說,窗體本質上具有通過控件使用的線程和資源,當窗體不可見時(在系統托盤中),這些資源仍在使用中。我可以做些什麼來最大限度地減少這些資源,而不是在恢復表單時殺死所有控件並重新繪製它們。

+0

您VS之外運行應用程序,是否正確?它會誇大應用程序的內存使用量。 – StingyJack 2008-11-04 20:14:13

回答

8

調用MiniMizeMemory()會是一個垃圾收集,修剪過程中的工作大小,然後壓縮進程的堆。

public static void MinimizeMemory() 
{ 
    GC.Collect(GC.MaxGeneration); 
    GC.WaitForPendingFinalizers(); 
    SetProcessWorkingSetSize(
     Process.GetCurrentProcess().Handle, 
     (UIntPtr)0xFFFFFFFF, 
     (UIntPtr)0xFFFFFFFF); 

    IntPtr heap = GetProcessHeap(); 

    if (HeapLock(heap)) 
    { 
     try 
     { 
      if (HeapCompact(heap, 0) == 0) 
      { 
       // error condition ignored 
      } 
     } 
     finally 
     { 
      HeapUnlock(heap); 
     } 
    } 
} 

[DllImport("kernel32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
internal static extern bool SetProcessWorkingSetSize(
    IntPtr process, 
    UIntPtr minimumWorkingSetSize, 
    UIntPtr maximumWorkingSetSize); 

[DllImport("kernel32.dll", SetLastError = true)] 
internal static extern IntPtr GetProcessHeap(); 

[DllImport("kernel32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
internal static extern bool HeapLock(IntPtr heap); 

[DllImport("kernel32.dll")] 
internal static extern uint HeapCompact(IntPtr heap, uint flags); 

[DllImport("kernel32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
internal static extern bool HeapUnlock(IntPtr heap); 
+0

哇,真棒的答案!我正在尋找這個;謝謝! – 2009-08-05 00:09:28

2

要清理未使用的內存,請使用GC.Collect()...雖然您應該閱讀爲什麼要這樣做,以及爲什麼它經常使用它通常是一個糟糕的主意。

如果你的意思是其他資源,你需要更具體。

3

你可能尋找此函數調用:SetProcessWorkingSetSize

如果執行API調用SetProcessWorkingSetSize與-1作爲參數,則Windows將修剪工作立即設置。

但是,如果大部分內存仍然被資源佔用,您還沒有釋放,最小化工作集將無能爲力。這與強制垃圾收集的建議相結合可能是你最好的選擇。

從您的應用程序描述中,您可能還需要驗證ListView消耗的內存以及數據庫訪問對象。我也不清楚你如何進行這些監控數據庫調用。您可能希望將其隔離爲單獨的對象,並避免在最小化時觸摸任何表單,否則程序將被迫保持控件加載並可訪問。您可以啓動一個單獨的線程進行監視,並將ListView.Count作爲參數傳遞。

一些來源:

.NET Applications and the Working Set

How much memory does my .Net Application use?