loopstate.Break(),loopState.Stop()和CancellationTokenSource.Cancel()之间有什么区别

zis*_*ish 15 .net windows parallel-processing for-loop c#-4.0

我有一个简单的问题,我有简单的Parallel for循环.这个for循环是windows服务的一部分.当有人停止服务时,我想停止循环.我可以找到三种停止并行的方法,即if条件.停止并行for循环的最佳方法是什么?有什么区别?

       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();

                }
            }
        });
Run Code Online (Sandbox Code Playgroud)

Arn*_*kas 20

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();
        }
    });
Run Code Online (Sandbox Code Playgroud)

loopState.Break()表示在当前线程上当前迭代之前的所有线程上完成所有迭代,然后退出循环(MSDN).

loopState.Stop()意味着尽快停止所有迭代(MSDN).


另一种终止执行的方法是调用token.ThrowIfCancellationRequested(),但是您需要处理OperationCanceledException异常:

public void MyMethod()
{
    try
    {
        Parallel.For(0, maximum_operations, options, (a, loopState) =>
        {
            // do work

            token.ThrowIfCancellationRequested();
        });
    }
    catch (OperationCanceledException)
    {
        // handle cancellation
    }
}
Run Code Online (Sandbox Code Playgroud)

所有这些方法都是终止执行的有效方法Parallel.For.您使用哪一个取决于您的要求.

例如:

  • 当您的Windows服务停止时,是否必须立即停止所有执行?然后你可以使用token.ThrowIfCancellationRequested()
  • 你的循环是否处理需要清理的IDisposable对象?然后你可以使用loopState.Break()loopState.Stop()

一些文章供参考: