Windows窗体在执行中抛出与视图样式相关的异常

时间:2013-06-20 21:28:47

标签: c# .net winforms awesomium

我有一个Windows表单应用程序,通常运行没有问题,但每隔一段时间(<1%的时间)我看到这样的错误:

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)

我之前处理过Visual Styles错误,因此确保使用该应用程序的计算机具有兼容的桌面主题。这个错误的奇怪之处在于,在抛出此异常之前,程序会启动并运行一段时间(例如30分钟)。我不明白在执行过程中视觉风格的状态会如何变化。

该应用程序由一个启动Windows窗体的控制台应用程序组成,该窗体使用Awesomium加载网页并响应javascript回调。

我在控制台应用上通过ThreadExceptionEventHandler收听Application.ThreadException来捕获错误。我突然意识到,当错误发生时,可能已经处理了窗体,但我不认为是这种情况,因为当我记录错误时,我可以访问窗体的实例成员,例如。 myForm.ToString()

由于我的代码都没有出现在堆栈跟踪中,我不确定还有什么能帮助描述这个错误。有没有人见过这样的事情?

1 个答案:

答案 0 :(得分: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对象处于10,000天花板上。