2

(We are developing an application in C#, WinForms + WPF, VS 2017, .NET Framework 4.7.1+)

We have run into issue regarding this error:

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

I have read numerous resources about this since:

However, its hard to reproduce the problem so we can figure out what parts of the application is responsible for the posting too much, and I am not clear on how we can detect/inspect/count the message queue, as indicated in the resources linked to above.

We have many UserControls, WinForms, as well as some WPF controls, that all update automatically from the remote server. All of the UCs contribute to posting messages to the queue, so its not about just inspecting one UC, but its the sum of all UCs that creates this problem.

Here are my questions:

  1. There is one message queue per Window, so if we are developing a desktop C# WinForms application, there is one and only one message queue for the entire app, correct?
  2. Is there a way, in code (C#), to look at the Message Queue and see if we are approaching the limit, 10 000 / second? We'd need some base counter, that can keep counting/checking regardless of where we are in the application, and preferably, see what part of the code is mostly responsible for this.
  3. Is there a difference between UI elements being "rendered in an async manner" vs sync? In the second link, its said that "There are too many UIElements being rendered in an async manner here". I have code that does this.Dispatcher.Invoke, so that's sync, right? I don't see why that would matter, its still a message posted to the queue?
  4. In one UC, we use Dispatcher.Invoke and set the System.Windows.Threading.DispatcherPriority to SystemIdle. What does that actually do?

I also wanted to share one method in one of the many UserControls. This is an WPF control, and this method is called to update GUI. Its called many times, for every element or update. What we did, however, is that this method will not return until done is true. Does this mean that the message queue has processed and handled the message, and is no longer on the queue, since we are using this.Dispatcher.Invoke, so its a sync message?

    void RunOnGUIThread(Action callback)
    {
        bool done = false;

        if (this.Dispatcher.Thread != System.Threading.Thread.CurrentThread)
        {
            this.Dispatcher.Invoke(delegate
            {
                try
                {
                    callback.DynamicInvoke(null);
                    done = true;
                }
                catch (Exception e) { }
            }, System.Windows.Threading.DispatcherPriority.SystemIdle);
        }
        else
        {
            callback.DynamicInvoke(null);
            done = true;
        }
        while (!done)
            System.Threading.Thread.Sleep(1);
    }

Generally, we have a lot of information in the desktop app, some in fixed menus that is always visible, other controls are loaded as they navigate the application etc. A lot of data gets automatically updated from the remote server if something happens to the data, so its worth to again point out that the message queue probably is affected by a lot of different UCs and updated on-the-fly, in real-time.

Any other tips how to debug or handle this in Visual Studio 2017 / C#?

halfer
  • 19,824
  • 17
  • 99
  • 186
Ted
  • 19,727
  • 35
  • 96
  • 154
  • You mention remote server, perhaps this may be useful - _[Error 0x80070718: Not enough quota is available to process this command](https://social.technet.microsoft.com/Forums/ie/en-US/c6c79225-dd97-41ce-aeb2-b3f46f235872/error-0x80070718-not-enough-quota-is-available-to-process-this-command?forum=itprovistaapps)_ –  Mar 07 '19 at 11:43
  • Thx, but im not sure I see the relation to this programming question? =) – Ted Mar 07 '19 at 12:06
  • 1
    It’s related to the error. On a side note, even if you are attempting to spam the message pump due to thread marshalling, the fact that you are using `Invoke` means that you block the worker thread until it completes thus putting in a nice _handbrake_ on your apps performance and limits the impact on the message pump. However `Invoke` can lead to thread deadlock so you want to avoid that. It is highly unlikely that your code above is the cause and again I urge you to consider the above link. Did you check the Event Log? Quota is _always_ relevant –  Mar 07 '19 at 13:05
  • 1) ...by the way, are you calling `Application.DoEvents`? 2) How many controls are visible at once? –  Mar 07 '19 at 13:14
  • Well, depends on what "page" the user has open. One page, an overview, has several hundreds of WPF blocks representing different things, that updates on-the-fly automatically. So, I cant really say, its very fluent and dynamic, what is actually shown on screen and depends on what they are doing... – Ted Mar 11 '19 at 09:48
  • Our application also suffers from this error and is similar to what you described. Did you found the culprit? – Nicolas Aug 18 '22 at 08:32

0 Answers0