В чем разница между 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()

некоторые статьи для справки: