Как очистить ThreadPool? [Microsoft System.Threading.ThreadPool] - PullRequest
0 голосов
/ 26 июля 2010

Можно ли очистить ThreadPool?

Удалить элементы из ThreadPool?

Что-нибудь в этом роде?

ThreadPool.QueueUserWorkItem(GetDataThread);
RegisteredWaitHandle Handle = ThreadPool.RegisterWaitForSingleObject(CompletedEvent, WaitProc, null, 10000, true);

Есть мысли?

Ответы [ 3 ]

4 голосов
/ 26 июля 2010

Я рекомендую использовать класс Task (добавлен в .NET 4.0), если вам нужно такое поведение. Он поддерживает Cancellation , и вы можете иметь любое количество задач, прослушивая один и тот же токен отмены, что позволяет отменить их все одним вызовом метода.

Обновлено (решение не для версии 4.0):

У вас действительно есть только два варианта. Первый: реализовать собственный демультиплексор событий (это намного сложнее, чем кажется из-за ограничения ожидания из 64 дескрипторов); Я не могу рекомендовать это - я должен был сделать это один раз (в неуправляемом коде), и это было отвратительно.

Это оставляет второй выбор: есть сигнал отменить задания. Естественно, RegisteredWaitHandle.Unregister может отменить часть RWFSO. QUWI является более сложным, но его можно сделать, уведомив действие о значении «токен». Когда действие выполняется, оно сначала сравнивает значение токена с его сохраненным значением токена; если они разные, то это ничего не должно делать.

Одна важная вещь, которую следует учитывать, это условия гонки. Просто имейте в виду, что между отменой действия и выполнением ThreadPool существует условие гонки, поэтому можно увидеть действия, выполняющиеся после отмены.

У меня есть сообщение в блоге об этой концепции , которое я называю "контекстами асинхронного обратного вызова". Тип CallbackContext, упомянутый в сообщении в блоге, доступен в библиотеке Nito.Async .

3 голосов
/ 26 июля 2010

Нет интерфейса для удаления элемента из очереди.Однако ничто не мешает вам «отравить» делегата, чтобы он немедленно вернулся.

edit

Исходя из того, что сказал Пол, я думаю, вы также можете захотетьрассмотреть конвейерную архитектуру, в которой у вас есть фиксированное число потоков, читающих из очереди блокировки (например, .NET 4.0's BlockingCollection на ConcurrentQueue).Таким образом, если вы хотите отменить элементы, вы можете просто получить доступ к очереди самостоятельно.

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

1 голос
/ 26 июля 2010

ThreadPool существует, чтобы помочь вам управлять вашими потоками.Вам вообще не нужно беспокоиться об его очистке, поскольку он будет принимать наилучшие решения по производительности от вашего имени.

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

посмотрите на некоторые из оптимизаций ThreadPool и идеи, лежащие в основеit.

Для моего второго замечания я нашел статью о Code Project , в которой реализован «Cancelable Threadpool», возможно, по некоторым вашим подобным причинам.Было бы неплохо начать искать, если вы собираетесь написать свой собственный.

...