В чем разница между loopstate.Break (), loopState.Stop() и CancellationTokenSource.Отмена()
У меня есть простой вопрос, у меня есть простая параллель для цикла. этот цикл for является частью службы windows. Я хочу остановить цикл, когда кто-то остановит службу. Я могу найти три способа остановиться параллельно, что находится в состоянии if. Каков наилучший способ остановить параллель для цикла и каковы различия?
CancellationTokenSource cancellationToken = new CancellationTokenSource();
ParallelOptions options = new ParallelOptions();
options.CancellationToken = cancellationToken.Token;
Parallel.For(0, maximum_operations, options, (a, loopState) =>
{
{
//Do something
if(!KeepProcessing)
{
//loopState.Break();
//loopState.Stop();
cancellationToken.Cancel();
}
}
});
1 ответов
CancellationToken
используется отмена сигнала.
loopState.Break()
и loopState.Stop()
используются для исполнение.
вот пример
Parallel.For(0, maximum_operations, options, (a, loopState) =>
{
// do work
// cancellationToken.Cancel() should be called externally
if(token.IsCancellationRequested)
{
// cancellation requested - perform cleanup work if necessary
// then call
loopState.Break();
// or
loopState.Stop();
}
});
loopState.Break()
означает завершение всех итераций во всех потоках, предшествующих текущей итерации в текущем потоке, а затем выход из цикла (MSDN).
loopState.Stop()
середины останавливают все итерации как только удобный (MSDN).
другим способом завершения выполнения является токен вызова.ThrowIfCancellationRequested (), но вам нужно будет обработать OperationCanceledException
исключения:
public void MyMethod()
{
try
{
Parallel.For(0, maximum_operations, options, (a, loopState) =>
{
// do work
token.ThrowIfCancellationRequested();
});
}
catch (OperationCanceledException)
{
// handle cancellation
}
}
все эти методы являются допустимыми способами прекращения выполнения Parallel.For
. Какой из них вы используете, зависит от ваших требований.
например:
- это важно тут остановите все выполнение, когда ваша служба windows остановились? Тогда вы могли бы использовать
token.ThrowIfCancellationRequested()
- имеет ли ваш цикл дело с IDisposable объектами, которые нуждаются в очистке? Тогда вы могли бы использовать
loopState.Break()
илиloopState.Stop()
некоторые статьи для справки: