Очередь сообщений Windows: как проверить количество «отправленных сообщений в очередь сообщений процесса» из С#

(Разрабатываем приложение на C#, WinForms + WPF, VS 2017, .NET Framework 4.7.1+)

Мы столкнулись с проблемой, связанной с этой ошибкой:

Win32Exception (0x80004005): недостаточно квоты для обработки этой команды.

Я прочитал множество ресурсов об этом с тех пор:

Однако воспроизвести проблему сложно, поэтому мы можем выяснить, какие части приложения слишком сильно ответственны за публикацию, и я не понимаю, как мы можем обнаружить/проверить/подсчитать очередь сообщений, как указано в связанных ресурсах. выше.

У нас есть много пользовательских элементов управления, WinForms, а также некоторые элементы управления WPF, которые автоматически обновляются с удаленного сервера. Все UC участвуют в отправке сообщений в очередь, поэтому проблема заключается не только в проверке одного UC, но и в сумме всех UC.

Вот мои вопросы:

  1. Для каждого окна существует одна очередь сообщений, поэтому, если мы разрабатываем настольное приложение C# WinForms, для всего приложения существует одна и только одна очередь сообщений, верно?
  2. Есть ли способ в коде (C#) просмотреть очередь сообщений и посмотреть, приближаемся ли мы к пределу, 10 000 в секунду? Нам понадобится какой-то базовый счетчик, который может продолжать считать/проверять независимо от того, где мы находимся в приложении, и желательно видеть, какая часть кода в основном отвечает за это.
  3. Есть ли разница между элементами пользовательского интерфейса, которые «отрисовываются асинхронно» и синхронно? Во второй ссылке сказано, что "Здесь слишком много элементов UIElements визуализируются асинхронно". У меня есть код, который выполняет this.Dispatcher.Invoke, значит, это синхронизация, верно? Я не понимаю, почему это имеет значение, это все еще сообщение, отправленное в очередь?
  4. В одном UC мы используем Dispatcher.Invoke и устанавливаем System.Windows.Threading.DispatcherPriority на SystemIdle. Что это на самом деле делает?

Я также хотел поделиться одним методом в одном из многих пользовательских элементов управления. Это элемент управления WPF, и этот метод вызывается для обновления графического интерфейса. Он вызывается много раз для каждого элемента или обновления. Однако мы сделали так, что этот метод не вернется, пока done не станет true. Означает ли это, что очередь сообщений обработала и обработала сообщение и больше не находится в очереди, поскольку мы используем 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/С#?


person Ted    schedule 07.03.2019    source источник
comment
Вы упоминаете удаленный сервер, возможно, это может быть полезно - Ошибка 0x80070718: Недостаточно квоты для обработки этой команды   -  person MickyD    schedule 07.03.2019
comment
Спасибо, но я не уверен, что вижу связь с этим вопросом программирования? знак равно   -  person Ted    schedule 07.03.2019
comment
Это связано с ошибкой. С другой стороны, даже если вы пытаетесь спамить поток сообщений из-за сортировки потоков, тот факт, что вы используете Invoke, означает, что вы блокируете рабочий поток до его завершения, тем самым устанавливая хороший ручной тормоз. на производительность ваших приложений и ограничивает влияние на поток сообщений. Однако Invoke может привести к взаимоблокировке потока, поэтому этого следует избегать. Крайне маловероятно, что ваш код выше является причиной, и я снова призываю вас рассмотреть приведенную выше ссылку. Вы проверяли журнал событий? Квота актуальна всегда   -  person MickyD    schedule 07.03.2019
comment
1) ...кстати, ты звонишь Application.DoEvents? 2) Сколько элементов управления видно одновременно?   -  person MickyD    schedule 07.03.2019
comment
Ну, зависит от того, какую страницу открыл пользователь. На одной странице, обзорной, есть несколько сотен блоков WPF, представляющих разные вещи, которые автоматически обновляются на лету. Так что я не могу сказать, что это очень плавно и динамично, то, что на самом деле отображается на экране, зависит от того, что они делают...   -  person Ted    schedule 11.03.2019