3

我有一个正常运行的 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)

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

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

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

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

4

1 回答 1

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 个上限。

于 2013-07-16T17:15:36.397 回答