我有一个简单的问题,下面有一个简单的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();

                }
            }
        });

最佳答案

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

终止执行的另一种方法是调用token.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()


  • 一些文章供引用:
  • MSDN: Cancellation
  • MSDN: How to: Stop or Break from a Parallel.For Loop
  • 08-26 23:19