Sometimes when Delegate.BeginInvoke is invoked, it takes more than one second to execute the delegate method.
What could be the reasons for the delay? I get this issue 1 or 2 times a day in an application which runs continuosly.
Please help me.
Thanks!
Диспетчер пула потоков следит за тем, чтобы на выполнение было разрешено столько потоков, сколько у вас имеется ядер ЦП. Как только один из них завершится, другой, ожидающий в очереди, может быть выполнен.
Дважды в секунду он повторно оценивает то, что происходит с запущенными потоками. Если они не завершаются, предполагается, что они заблокированы, и разрешает выполнение другого ожидающего потока. На типичном двухъядерном процессоре сразу же запускаются два потока, третий поток запускается через одну секунду, четвертый поток через 1,5 секунды и так далее.
Ну вот и ваш второй. Исправление Q&D заключается в использовании ThreadPool.SetMinThreads (), но это решение проблемы с кувалдой. Настоящая проблема заключается в том, что ваша программа использует потоки пула потоков для длительных задач. Либо потому, что они выполняют много кода, либо потому, что они блокируют какой-либо запрос ввода / вывода. Последний случай встречается чаще.
Чтобы решить эту проблему, не используйте поток пула потоков для такого блокирующего потока, а вместо этого используйте класс Thread. Не делайте этого, если потоки на самом деле сжигают циклы ЦП, вы все замедляете. Легко сказать, вы увидите 100% загрузку процессора в Taskmgr.exe
Поскольку вы используете Delegate.BeginInvoke
, то косвенно вы используете ThreadPool
. ThreadPool
перерабатывает завершенные потоки и позволяет их повторно использовать без затрат на создание новых потоков и разрыв завершенных потоков.
Итак ... когда вы используете Delegate.BeginInvoke
, вы добавляете вызываемый метод в очередь, как только ThreadPool
считает, что у него есть доступный поток для вашу задачу он выполнит. Однако, если в пуле потоков
нет доступных потоков, вам придется ждать.
System.Threading.ThreadPool
имеет несколько свойств и методов, чтобы показать, сколько потоков доступно, максимальное количество и т. Д. Я бы попытался отслеживать эти подсчеты, чтобы увидеть, похоже ли, что ThreadPool
используется намазывать тонким слоем.
Если это так, то лучшим решением будет гарантировать, что ThreadPool
используется только для краткосрочных (небольших) задач. Если он используется для длительных задач, то эти задачи следует изменить так, чтобы они использовали свой собственный выделенный поток, а не занимали ThreadPool.
Вы можете установить приоритет BeginInvoke?
http: //msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherpriority.aspx
Есть ли у вас другие ожидающие вызовы BeginInvoke?
«Если несколько вызовов BeginInvoke выполняются в одном и том же DispatcherPriority, они будут выполняться в том порядке, в котором были сделаны вызовы. "