Win32Exception: Operation completed successfully

2020-02-11 07:11发布

问题:

The following code crashes with an exception :

MyWindow wnd = new MyWindow();
wnd.Show(); //here an exception occurs

Exception is rather strange but as I understand its a bug in .net

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()

MyWindow object is a window with some vector graphics inside, but not too much. Also, it happens when 10-20 MyWindow objects have been opened and closed already.

Solution: The reason was a leak of GDI objects.They were creating in my low level code containing a mistake. So, the problem had no concern to MyWindow object.

回答1:

It doesn't bomb on a winapi error code, the actual error code is E_FAIL, a COM error code. Which is very unhelpful to diagnose anything, it doesn't mean anything more than "couldn't do it, no idea why". How GetDC() can produce that error code is very hard to guess, I suspect it is environmental with something hooking the winapi function. Perhaps something similar to remote desktop or a screen recorder. Do try running this on another machine.

The "normal" reason for GetDC() failure is a handle leak. Windows stops giving a process more handles when it has consumed 10,000 of them already. Something you can diagnose with TaskMgr.exe, Processes tab. View + Select Columns and tick Handles, USER Objects and GDI Objects. First check the list of processes and verify that you don't have a process that consumes a lot of them. The total number of GDI Objects for all processes in a session is limited by the session pool size. Next run your program and keep an eye on the values for your process.



回答2:

We have this problem in our project too...

we were putting all view and view models to stack and then showing one by one them. Solution was to show elements one by one without making the stack.



标签: c# wpf exception