2013-06-20 18 views
2

我有一個正常運行沒有問題的Windows窗體應用程序,但每隔一段時間(時間< 1%),我看到類似這樣的錯誤:Windows窗體拋出視覺樣式相關的異常中期執行

Visual Styles-related operation resulted in an error because no visual style is currently active. at System.Windows.Forms.VisualStyles.VisualStyleRenderer.get_Handle() at System.Windows.Forms.VisualStyles.VisualStyleRenderer.DrawBackground(IDeviceContext dc, Rectangle bounds, Rectangle clipRectangle) at System.Windows.Forms.GroupBoxRenderer.DrawThemedGroupBoxWithText(Graphics g, Rectangle bounds, String groupBoxText, Font font, Color textColor, TextFormatFlags flags, GroupBoxState state) at System.Windows.Forms.GroupBoxRenderer.DrawGroupBox(Graphics g, Rectangle bounds, String groupBoxText, Font font, TextFormatFlags flags, GroupBoxState state) at System.Windows.Forms.GroupBox.OnPaint(PaintEventArgs e) at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer) at System.Windows.Forms.Control.WmPaint(Message& m) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.GroupBox.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

我已經處理過視覺樣式錯誤,所以確保使用該應用程序的機器具有兼容的桌面主題。這個錯誤有什麼奇怪之處在於,在引發這個異常之前,程序一段時間(例如,30分鐘)開始並快樂地運行。我不明白視覺風格的狀態在執行過程中會如何改變。

該應用程序由一個控制檯應用程序組成,該應用程序啓動一個Windows窗體,該窗體使用Awesomium加載網頁並響應JavaScript回調。

我在控制檯應用程序上聽到ThreadExceptionEventHandler正在聽Application.ThreadException的錯誤。它發生在我可能窗口錯誤發生時處置,但我不認爲這是這種情況,因爲當我登錄錯誤,我可以訪問窗體的實例成員例如。 myForm.ToString()

由於我的代碼沒有在堆棧跟蹤中顯示,我不確定還有什麼可以幫助描述此錯誤。有沒有人見過這樣的事情?

+1

很難解釋這個例外,從來沒有見過這樣的一次。你應該去尋找你的程序中的句柄泄漏。 –

+3

有三種句柄,TaskMgr.exe也可以顯示USER對象和GDI對象。對於泄漏kernel32句柄非常罕見,當你不應該調用Dispose()時,很容易泄漏另外兩個句柄。特別是用戶手柄很容易永久泄漏,Controls.Clear()或Remove(),然後不處置刪除的控件就可以完成。 –

回答

2

Hans Passant是正確的,這是一個GDI處理泄漏。我無法在我的開發環境中重現它,所以需要將一些日誌記錄添加到我的服務器。如果它幫助其他人,這裏是我如何通過調用GetGuiResources函數得到我需要的信息。

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    static extern int GetGuiResources(IntPtr hProcess, int uiFlags); 

,並使用它來獲取句柄數:

var p = Process.GetCurrentProcess(); 
    kernel = p.HandleCount; 

    gdiObjects = GetGuiResources(p.Handle, 0); 
    userObjects = GetGuiResources(p.Handle, 1); 

    gdiObjectsPeak = GetGuiResources(p.Handle, 2); 
    userObjectsPeak = GetGuiResources(p.Handle, 4); 

一旦在地方,我看到GDI對象是在10000天花板時出現死機。

+0

你確實需要解釋爲什麼這在Taskmgr.exe中不可見 –

+0

我簡化了我的故事。我實際上在12臺服務器上添加了日誌記錄,14小時後其中一臺服務器再次發生崩潰。我確定計數器在任務管理器中可見,但放樣不可行。 – mafue