Delegate.BeginInvoke Задержка - PullRequest
       4

Delegate.BeginInvoke Задержка

7 голосов
/ 06 августа 2010

Иногда при вызове Delegate.BeginInvoke метод делегата занимает больше одной секунды.

Какие могут быть причины задержки? Я получаю эту проблему 1 или 2 раза в день в приложении, которое работает непрерывно.

Пожалуйста, помогите мне.

Спасибо!

Ответы [ 3 ]

7 голосов
/ 06 августа 2010

Менеджер пула потоков гарантирует, что только столько потоков разрешено выполнять, сколько у вас ядер ЦП.Как только один завершает работу, другой, ожидающий в очереди, может выполняться.

Дважды в секунду он переоценивает, что происходит с запущенными потоками.Если они не завершаются, предполагается, что они заблокированы, и позволяет запустить другой ожидающий поток.На типичном двухъядерном процессоре вы сразу получите два потока, третий поток запускается через одну секунду, четвертый поток через 1,5 секунды, и так далее.Исправление Q & D заключается в использовании ThreadPool.SetMinThreads (), но это решение кувалдой.Реальная проблема заключается в том, что ваша программа использует потоки пула потоков для длительных задач.Либо потому, что они выполняют много кода, либо потому, что они блокируют какой-то запрос ввода-вывода.Последний является наиболее распространенным случаем.

Чтобы решить эту проблему, нужно не использовать поток пула потоков для такого блокирующего потока, а вместо этого использовать класс Thread.Не делайте этого, если потоки фактически сжигают циклы процессора, вы все замедляете.Легко сказать, вы увидите 100% загрузки процессора в Taskmgr.exe

4 голосов
/ 06 августа 2010

Поскольку вы используете Delegate.BeginInvoke, вы косвенно используете ThreadPool.ThreadPool перерабатывает завершенные потоки и позволяет повторно использовать их без затрат на создание новых потоков и срыв завершенных потоков.

Итак ... когда вы используете Delegate.BeginInvoke, вы добавляете методчтобы быть вызванным в очередь, как только ThreadPool решит, что у него есть доступный поток для вашей задачи, он будет выполняться.Однако, если у ThreadPool нет доступных потоков, вы будете ждать.

System.Threading.ThreadPool имеет несколько свойств и методов, чтобы показать, сколько потоков доступно, максимумов и т. Д.эти подсчеты, чтобы увидеть, похоже ли, что ThreadPool распространяется тонко.

Если это так, то лучшее решение - убедиться, что ThreadPool используется только длякраткосрочные (малые) задачи.Если он используется для долгосрочных задач, то эти задачи должны быть изменены, чтобы использовать их собственный выделенный поток, а не занимать ThreadPool.

2 голосов
/ 06 августа 2010

Можете ли вы установить приоритет BeginInvoke?

http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherpriority.aspx

Есть ли у вас другие ожидающие вызовы BeginInvoke?

"Если натот же DispatcherPriority, они будут выполняться в том же порядке, в котором были сделаны вызовы. "

http://msdn.microsoft.com/en-us/library/ms591206.aspx

...