Windows消息队列:如何从C#

时间:2019-03-07 11:21:33

标签: c# wpf winforms windows-messages

(我们正在开发C#,WinForms + WPF,VS 2017,.NET Framework 4.7.1+的应用程序)

关于此错误,我们遇到了问题:

  

Win32Exception(0x80004005):没有足够的配额可用于处理此命令。

自此以来,我已经阅读了许多相关资源:

但是,它很难重现该问题,因此我们可以弄清楚应用程序的哪些部分过多地负责发布,而且我不清楚如何检测/检查/计数消息队列,如上面链接的资源。

我们有许多UserControls,WinForms以及一些WPF控件,它们都可以从远程服务器自动更新。所有UC都有助于将消息发布到队列中,因此,它不仅是检查一个 UC,还包括所有造成此问题的UC的总和。

这是我的问题:

  1. 每个窗口有一个消息队列,所以如果我们正在开发一个桌面C#WinForms应用程序,那么整个应用程序只有一个消息队列,对吗?
  2. 在代码(C#)中是否可以查看消息队列,并查看是否正在接近10 000 /秒的限制?我们需要一些基础计数器,无论我们在应用程序中的什么位置,该计数器都可以继续计数/检查,并且最好查看代码的哪一部分对此负责。
  3. “以异步方式呈现” UI元素和同步元素之间是否有区别? In the second link,它说“这里有太多以异步方式渲染的UIElement”。我有执行this.Dispatcher.Invoke的代码,因此可以同步,对吗?我不明白为什么这很重要,它仍然是一条消息发布到队列中?
  4. 在一个UC中,我们使用Dispatcher.Invoke并将System.Windows.Threading.DispatcherPriority设置为SystemIdle。这实际上是做什么的?

我还想在众多UserControl之一中共享一种方法。这是一个WPF控件,并且调用此方法来更新GUI。对于每个元素或更新,它都多次调用。但是,我们所做的是,只有donetrue时,此方法才会返回。这是否意味着消息队列已经处理并处理了消息,并且由于我们正在使用this.Dispatcher.Invoke而不再在队列中,所以它是同步消息?

    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);
    }

通常,我们在桌面应用程序中有很多信息,其中一些信息始终固定在固定菜单中,其他控件在浏览应用程序时也会加载等。如果发生某些情况,很多数据会从远程服务器自动更新数据,因此值得一提的是,消息队列可能受许多不同的UC的影响,并实时进行实时更新。

还有其他技巧和指针如何在Visual Studio 2017 / C#中调试或处理吗?

0 个答案:

没有答案