Windows Message Queue: How to inspect the nbr of 'posted messages to a process' message queue' from C#

0

(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#?

c#
wpf
winforms
windows-messages
asked on Stack Overflow Mar 7, 2019 by Ted • edited Jun 6, 2020 by halfer

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0