Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Win32Exception (0x80004005): Not enough quota is available to process this command. #137

Closed
walterlv opened this issue Dec 10, 2018 · 12 comments

Comments

@walterlv
Copy link
Contributor

  • .NET Core Version: 3.0 Preview1
  • Windows version: Windows 10 / 7 SP1
  • Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes

Problem description:

We sometimes get an Win32Exception (0x80004005) report from end-user' device, but we can't determine what happed at that time.

Actual behavior:

We sometimes get a feedback from the end-user that the app freezes at that moment when the exception is thrown.

System.ComponentModel.Win32Exception (0x80004005): Not enough quota is available to process this command.
   at MS.Win32.UnsafeNativeMethods.PostMessage(HandleRef hwnd, WindowMessage msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndTarget.UpdateWindowSettings(Boolean enableRenderTarget, Nullable`1 channelSet)
   at System.Windows.Interop.HwndTarget.UpdateWindowPos(IntPtr lParam)
   at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

Expected behavior:

There is no such an exception.

Minimal repro:

Note that we still can't figure out all the reproduction, but I find a simple procedure to reproduce it.

  1. Launch a malicious app sending message to the target WPF app continuously;
  2. The WPF app will get the Win32Exception (0x80004005).
@vatsan-madhavan
Copy link
Member

Message queues have a limit described in the documentation for PostMessage. Flooding an application with window messages is expected to cause this exception. This is by design.

BTW, this will happen on WPF on .NET Framework as well.

@walterlv
Copy link
Contributor Author

@vatsan-madhavan So, what's the recommended way to avoid this kind of app crash?

@vatsan-madhavan
Copy link
Member

An application architecture that hits that 10000 message limit would need to be changed, I’m afraid. Also, see But then we ran into problems when we started posting 10,000 messages per second.

@vatsan-madhavan
Copy link
Member

vatsan-madhavan commented Dec 10, 2018

This kind of bug report is observed in other UI technologies as well. We hear about this either as a bug report or a crash report now and then, and we usually recommend looking into the application architecture and finding out why the message queue is flooding rapidly.

WPF has a flag that you could use to aid in such a diagnosis. Please take a look at BaseCompatibilityPreferences.HandleDispatcherRequestProcessingFailure. Setting this to Throw can bring the problem to your attention as soon as it happens, and allow you to diagnose it accurately. Also take a look at Reset, but I wouldn't recommend using Reset as the default or as a replacement for diagnosing the underlying problem.

When you set it to Throw, set the debugger to catch the exception in Dispatcher.OnRequestProcessingFailure and puzzle out why the queue is full from there. Since the message queue is a kernel mode component, you can only get indirect clues to what is going on.

[Additional debugging tips courtesy of my colleague Sam Bent]

@lamposu
Copy link

lamposu commented Feb 1, 2019

@vatsan-madhavan I also met this issue in .net framework 4.6.1, and i can't find this flag :BaseCompatibilityPreferences.HandleDispatcherRequestProcessingFailure in 4.6.1

@vatsan-madhavan
Copy link
Member

That flag doesn’t exist in 4.6.1. It was introduced in 4.7.1.

@stevenbrix
Copy link
Contributor

Thanks @vatsan-madhavan for the detailed information, it's always nice to learn something every day.

I'm going to close this issue since it seems that this issue is by design (and unrelated to WPF specifically). @walterlv if you think that is wrong and there is actually a fundamental issue with WPF, please reply and we can continue the discussion.

@walterlv
Copy link
Contributor Author

walterlv commented Apr 6, 2019

@stevenbrix Thanks for your reply.
I'll try to set the BaseCompatibilityPreferences.HandleDispatcherRequestProcessingFailure flag to Reset to avoid this app crash on machines that has net471 runtime. After we migrating our product to .NET Core 3 we can use this flag ignoring machine runtime version.
So if you have some other recommended method to solve this issue in .NET Framework 4.7 or lower, I'm very glad to share it to others.
Thanks again.

@rvnlord
Copy link

rvnlord commented Apr 30, 2019

I found out that sInce .NET 4.7 this happens pretty randomly on locks, I initially thought my problem was caused by deadlocks but it was caused by this. the reason for this to happen is using the same synchronization object in one method that has await keyword and in another that doesn't. Lets say you got method without await on button click and the other one with await that executes as some kind of delayed response. If you click button 2-3 times everything will be okay, but if you click it repeatedly 5-15, it will freeze the app and eventually throw 'not enough quota'. Fix for this is to make the other method async, without changing any logic. I recently debugged this scenario extensively and I am sure it is not caussed by my code.

@jinek
Copy link

jinek commented Jul 31, 2019

I found out that sInce .NET 4.7 this happens pretty randomly on locks, I initially thought my problem was caused by deadlocks but it was caused by this. the reason for this to happen is using the same synchronization object in one method that has await keyword and in another that doesn't. Lets say you got method without await on button click and the other one with await that executes as some kind of delayed response. If you click button 2-3 times everything will be okay, but if you click it repeatedly 5-15, it will freeze the app and eventually throw 'not enough quota'. Fix for this is to make the other method async, without changing any logic. I recently debugged this scenario extensively and I am sure it is not caussed by my code.

Could you please attach the solution which reproduces the behavior?

@NickeManarin
Copy link

@rvnlord I would like to see a solution that reproduces the behavior too.

@NeverMorewd
Copy link

same issue
I load a winform which contains a wpf window with STA Thread

@ghost ghost locked as resolved and limited conversation to collaborators Apr 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants