Остановка всех потоков в.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>), что гарантирует вам полный контроль над всеми потоками.

Другие вопросы по тегам