В чем разница между loopstate.Break (), loopState.Stop () и CancellationTokenSource.Cancel () - PullRequest
14 голосов
/ 11 января 2012

У меня простой вопрос, у меня следующий простой параллель для цикла. это цикл 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 Ответ

19 голосов
/ 11 января 2012

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 ).


Другим способом прекратить выполнение является вызов токена.необходимо обработать исключение 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()

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...