我有一个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()
由于我的代码都没有出现在堆栈跟踪中,我不确定还有什么能帮助描述这个错误。有没有人见过这样的事情?
答案 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天花板上。