Win32异常:操作成功完成

6
下面的代码会因为异常而崩溃:
MyWindow wnd = new MyWindow();
wnd.Show(); //here an exception occurs

异常相当奇怪,但据我理解这是 .net 中的一个 bug。

System.ComponentModel.Win32Exception (0x80004005): The operation completed successfully
   at MS.Win32.UnsafeNativeMethods.GetDC(HandleRef hWnd)
   at System.Windows.Interop.HwndTarget..ctor(IntPtr hwnd)
   at System.Windows.Interop.HwndSource.Initialize(HwndSourceParameters parameters)
   at System.Windows.Interop.HwndSource..ctor(HwndSourceParameters parameters)
   at System.Windows.Window.CreateSourceWindow(Boolean duringShow)
   at System.Windows.Window.CreateSourceWindowDuringShow()
   at System.Windows.Window.SafeCreateWindowDuringShow()
   at System.Windows.Window.ShowHelper(Object booleanBox)
   at System.Windows.Window.Show()

我的窗口对象是一个带有一些矢量图形的窗口,但不是太多。此外,当已经打开和关闭了10-20个MyWindow对象时,它会出现。

解决方案:问题原因是GDI对象泄漏。这些对象在我低级代码中创建时出现了错误。因此,该问题与MyWindow对象无关。


1
如果您正在创建不属于主线程的窗口,您可能已经有太多的“Dispatchers”处于活动状态。请尝试按照Connect问题提出的解决方法进行操作。也许您的窗口已经使用了太多资源。 - Pavel Gatilov
在MyWindow的构造函数中你做了什么?你重写了show方法吗? - rekire
@rekire 不,我没有覆盖。构造函数中唯一的一行是InitializeComponent()。 - HelloWorld
我遇到了与您相同的问题,但情境不同。注意到@rekire提到了Show()方法。由于我在做MVVM,我正在覆盖App.xaml.cs中的Startup()方法并在其中使用window.Show()。当我尝试使用BluetoothWin32Authentication的处理程序时,这可能会导致问题吗? - Mehrad
我在一个新项目中只用了一行代码,只有一个按钮,没有使用MVVM或其他任何东西,但仍然得到相同的错误。 - Mehrad
2个回答

11

它不会因为WinAPI错误代码而崩溃,实际的错误代码是E_FAIL,这是一种COM错误代码。这对于诊断任何问题都没有什么帮助,它只意味着“无法完成,不知道原因”。GetDC()函数如何产生该错误代码非常难以猜测,我怀疑这是由于某些挂钩WinAPI函数的环境所导致的,可能类似于远程桌面或屏幕录制等功能。请尝试在另一台机器上运行此程序。

GetDC()失败的“正常”原因是句柄泄漏。当一个进程已经使用了10000个句柄时,Windows不再给该进程分配更多句柄。您可以使用TaskMgr.exe的Processes选项卡来进行诊断。在"View + Select Columns"中勾选Handles、USER Objects和GDI Objects。首先检查进程列表并验证您是否拥有消耗大量句柄的进程。会话池大小限制了所有进程的GDI对象总数。接下来运行您的程序,并关注该进程的值。


为什么垃圾回收不处理句柄?为什么垃圾回收要等到句柄数量达到10k才执行? - Zafar
1
GC的工作不是管理句柄,它只管理内存。释放句柄的工作应该由finalizer来完成。当程序员忽略Dispose()方法时,程序就会在没有及时运行的情况下失败。 - Hans Passant

0

我们的项目中也遇到了这个问题...

我们之前把所有的视图和视图模型都放在一个栈里,然后逐个显示它们。解决方案是不使用栈,逐个显示元素。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接