Остановка всех потоков в.NET ThreadPool?
Я использую ThreadPool в.NET для выполнения некоторых веб-запросов в фоновом режиме, и мне нужна кнопка "Стоп" для отмены всех потоков, даже если они находятся в процессе выполнения запроса, поэтому простой bool не будет выполнять работа.
Как я могу это сделать?
3 ответа
Правильный способ справиться с этим - иметь флаговый объект, который вы сигнализируете.
Код, работающий в этих потоках, должен периодически проверять этот флаг, чтобы увидеть, должен ли он выйти.
Например, объект ManualResetEvent подходит для этого.
Затем вы можете попросить потоки выйти так:
evt.Set();
и внутри потоков вы можете проверить это следующим образом:
if (evt.WaitOne(0))
return; // or otherwise exit the thread
Во-вторых, поскольку вы используете пул потоков, происходит следующее: все элементы, которые вы поставили в очередь, будут по-прежнему обрабатываться, но если вы добавите приведенный выше оператор if к самому началу метода потока, он немедленно завершится., Если это не достаточно хорошо, вы должны построить свою собственную систему, используя обычные потоки, таким образом, вы получите полный контроль.
Да, и просто чтобы убедиться, не используйте Thread.Abort. Попросите потоки красиво выйти, не убивайте их.
Ваша ситуация в значительной степени является каноническим примером использования модели отмены в.NET Framework.
Идея состоит в том, чтобы создать объект CancellationToken и сделать его доступным для операции, которую вы, возможно, захотите отменить. Ваша операция иногда проверяет свойство токена IsCancellationRequested или вызывает ThrowIfCancellationRequested.
Вы можете создать CancellationToken и запросить отмену через него, используя класс CancellationTokenSource.
Эта модель отмены прекрасно интегрируется с параллельной библиотекой.NET Task и довольно легка, более того, чем использование системных объектов, таких как ManualResetEvent (хотя это тоже вполне допустимое решение).
Если вы собираетесь остановить / отменить обработку чего-либо в другом потоке, ThreadPool
это не лучший выбор, вы должны использовать Thread
вместо этого, и управляйте всеми ими в контейнере (например, глобальный List<Thread>
), что гарантирует вам полный контроль над всеми потоками.