(Разрабатываем приложение на C#, WinForms + WPF, VS 2017, .NET Framework 4.7.1+)
Мы столкнулись с проблемой, связанной с этой ошибкой:
Win32Exception (0x80004005): недостаточно квоты для обработки этой команды.
Я прочитал множество ресурсов об этом с тех пор:
- Загадочный Недостаточно квоты обработать эту команду в WinRT-порте DataGrid
- https://social.msdn.microsoft.com/Forums/en-US/d778c6e0-c248-4a1a-9391-28d038247578/mysterious-8220not-enough-quota-is-accessible-to-process-this-command8221-in-winrt-port-of
- https://github.com/dotnet/wpf/issues/137
- https://social.msdn.microsoft.com/Forums/en-US/e28dafb1-3ef6-484e-924a-89aff714b3e9/begininvoke-messages-not-getting-stuck?forum=winforms
Однако воспроизвести проблему сложно, поэтому мы можем выяснить, какие части приложения слишком сильно ответственны за публикацию, и я не понимаю, как мы можем обнаружить/проверить/подсчитать очередь сообщений, как указано в связанных ресурсах. выше.
У нас есть много пользовательских элементов управления, WinForms, а также некоторые элементы управления WPF, которые автоматически обновляются с удаленного сервера. Все UC участвуют в отправке сообщений в очередь, поэтому проблема заключается не только в проверке одного UC, но и в сумме всех UC.
Вот мои вопросы:
- Для каждого окна существует одна очередь сообщений, поэтому, если мы разрабатываем настольное приложение C# WinForms, для всего приложения существует одна и только одна очередь сообщений, верно?
- Есть ли способ в коде (C#) просмотреть очередь сообщений и посмотреть, приближаемся ли мы к пределу, 10 000 в секунду? Нам понадобится какой-то базовый счетчик, который может продолжать считать/проверять независимо от того, где мы находимся в приложении, и желательно видеть, какая часть кода в основном отвечает за это.
- Есть ли разница между элементами пользовательского интерфейса, которые «отрисовываются асинхронно» и синхронно? Во второй ссылке сказано, что "Здесь слишком много элементов UIElements визуализируются асинхронно". У меня есть код, который выполняет
this.Dispatcher.Invoke
, значит, это синхронизация, верно? Я не понимаю, почему это имеет значение, это все еще сообщение, отправленное в очередь? - В одном 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/С#?
Invoke
, означает, что вы блокируете рабочий поток до его завершения, тем самым устанавливая хороший ручной тормоз. на производительность ваших приложений и ограничивает влияние на поток сообщений. ОднакоInvoke
может привести к взаимоблокировке потока, поэтому этого следует избегать. Крайне маловероятно, что ваш код выше является причиной, и я снова призываю вас рассмотреть приведенную выше ссылку. Вы проверяли журнал событий? Квота актуальна всегда - person MickyD   schedule 07.03.2019Application.DoEvents
? 2) Сколько элементов управления видно одновременно? - person MickyD   schedule 07.03.2019