Как я могу убить все потоки, созданные Parallel.ForEach из моего основного потока? - PullRequest
4 голосов
/ 19 мая 2011

Вот сценарий:

У меня запущена служба Windows.OnStart() устанавливает таймер, который будет вызывать функцию (назовем ее ProcessEvent()).Код внутри ProcessEvent является критическим разделом, поэтому только один поток может сделать следующее:

private void ProcessEvent(object sender, ElapsedEventArgs e)
{
    lock(lockObj)
    {
        string[] list = GetList();
        Parallel.ForEach(list, item => { ProcessItem(item) });
    }
}

ProcessItem потенциально может занять много времени.

Теперь, когда служба работаетостановил мой OnStop() в данный момент просто останавливается и избавляется от таймера.Однако я заметил, что даже после остановки службы существуют потоки, которые все еще работают ProcessItem().

Итак, как я могу уничтожить все запущенные потоки, созданные этой программой (в основном те, которые были созданы Parallel.ForEach, но также и те, которые ожидают блокировки в ProcessEvent)?

IЯ знаю, что если бы я сам создал поток, я мог бы установить для isBackground значение true, и все это будет убито, когда процесс умрет, но я не создаю эти потоки вручную.

Ответы [ 2 ]

8 голосов
/ 19 мая 2011

Используйте структуру CancellationToken . Прочитайте это и это для получения дополнительной информации.

// Setup the cancellation mechanism.
var cts = new CancellationTokenSource();
var po = new ParallelOptions();
po.CancellationToken = cts.Token;

// Run the enumerator in parallel.
Parallel.ForEach(list, po, 
  (item) =>
  {
    ProcessItem(item);
    po.CancellationToken.ThrowIfCancellationRequested();
  });

// Call Cancel to make Parallel.ForEach throw.
// Obviously this must done from another thread.
cts.Cancel();
5 голосов
/ 19 мая 2011

Посмотрите на перегрузки Parallel.ForEach , которые принимают делегата с параметром ParallelLoopState . Проверьте флаг в теле, чтобы увидеть, должно ли выполнение продолжаться, иначе убейте его:

Parallel.ForEach(list, (item, pls) => { 
    if(quit)pls.Stop();
    else
        ProcessItem(item);
});
...