C# parallel.foreach-loopState.Stop()与取消

C# parallel.foreach-loopState.Stop()与取消,c#,cancellation-token,C#,Cancellation Token,取消操作与循环状态操作(中断/停止)之间有什么区别 为什么我要使用ParallelOptions取消操作而不是loopState.Break()或loopState.Stop()或反之亦然?参见此 “设置取消令牌允许您中止调用(请记住,当委托引发异常时,异常会被吞没,并且只有在所有其他委托都被执行后,才由调用重新引发)。” 情景1。想象一下,你有一个用户将要向所有的前[女|男]朋友发送消息。他们点击“发送”,然后恢复理智,想要取消它。通过使用取消令牌,他们能够阻止进一步的消息传出。因此,如果您有

取消操作与循环状态操作(中断/停止)之间有什么区别

为什么我要使用ParallelOptions取消操作而不是
loopState.Break()
loopState.Stop()或反之亦然?

参见此

“设置取消令牌允许您中止调用(请记住,当委托引发异常时,异常会被吞没,并且只有在所有其他委托都被执行后,才由调用重新引发)。”

情景1。想象一下,你有一个用户将要向所有的前[女|男]朋友发送消息。他们点击“发送”,然后恢复理智,想要取消它。通过使用取消令牌,他们能够阻止进一步的消息传出。因此,如果您有一个允许取消的长时间运行的进程,请使用取消令牌

另一方面,场景2,如果您不希望进程被中断,那么使用普通循环状态异常,这样异常将被吞没,直到所有线程完成


场景3如果您有一个I/O密集型进程,那么您可能希望使用async/await而不是parallel.foreach。查看Microsoft。

ParallelLoopState.Break
/
Stop
具有特定于循环执行的定义良好的语义。也就是说,通过使用这些,您可以非常具体地了解您希望循环如何终止。另一方面,
CancellationToken
是TPL中的通用停止机制,因此它对并行循环没有任何特殊作用。使用令牌的优点是它可以在其他TPL功能中共享,因此您可以拥有由同一令牌控制的任务和循环

我不确定它是否回答了最初的问题,即我何时会在取消时使用loopState。。。你能把这个答案细分并解释一下吗?我很欣赏不同的情景。实际上,CancellationToken对并行循环有特殊的影响。如果取消了ParallelOptions.CancellationToken,则ParallelLoopState.ShouldExitCurrentIteration将变为false。因此,长时间运行的任务(可能没有被循环取消)可以检查此属性并停止其工作@CagatayKalan不确定你的评论是否正确。首先,您可能指的是
true
,而不是
false
。其次,使用
Break
Stop
时,
ShouldExitCurrentIteration
也设置为
true
,因此它不仅仅是
CancellationToken
的专利。此外,对
ShouldExitCurrentIteration
状态的检查是由循环自动完成的,除非您想要实现一些特殊的逻辑,否则不需要您自己的代码来完成。
private static CancellationTokenSource cts;
public static loopingMethod()
{
cts = new CancellationTokenSource();
try
{
    ParallelOptions pOptions = new ParallelOptions();
    pOptions.MaxDegreeOfParallelism = 4;
    pOptions.CancellationToken = cts.Token;
    Parallel.ForEach(dictObj, pOptions, (KVP, loopState) =>
    {
        pOptions.CancellationToken.ThrowIfCancellationRequested();
        parallelDoWork(KVP.Key, KVP.Value, loopState);
     }); //End of Parallel.ForEach loop
 }
 catch (OperationCanceledException e)
 {
 //Catestrophic Failure
 return -99;
 }
}

public static void parallelDoWork(string Id, string Value, ParallelLoopState loopState)
{
   try{
      throw new exception("kill loop");
   }
   catch(exception ex)
   {
       if(ex.message == "kill loop")
       {
           cts.Cancel();
           //Or do I use loopState here?
       }
   }
}