Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当一个线程与If语句匹配时,如何中断Parallel.For循环?_C#_Parallel Processing - Fatal编程技术网

C# 当一个线程与If语句匹配时,如何中断Parallel.For循环?

C# 当一个线程与If语句匹配时,如何中断Parallel.For循环?,c#,parallel-processing,C#,Parallel Processing,所以在我的示例中,我希望在控制台中显示完成first值的第一个线程,然后将其显示出来,以便所有剩余的线程都被中止。下面是我现在拥有的代码,它演示了这个问题 public static void test() { int Loop = 0; Parallel.For(0, 2000, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, (i,

所以在我的示例中,我希望在控制台中显示完成first值的第一个线程,然后将其显示出来,以便所有剩余的线程都被中止。下面是我现在拥有的代码,它演示了这个问题

    public static void test()
    {
        int Loop = 0;

        Parallel.For(0, 2000, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, (i, End) =>
        {
            Loop++;
            Console.WriteLine(Loop);

            if (Loop == 1000)
            {
                Console.WriteLine("Break!");
                End.Break();
            }
        });
    }
当它在这里完成时,是一个输出到控制台的片段

985
987
983
Break!
Break!
992
998
Break!
Break!
00:00:00.7217394

所以现在我不知道当一个线程与if语句匹配时,如何让它一起停止。任何帮助都将不胜感激

Parallel.Forxxx支持
CancellationToken
s。只需创建一个
CancellationTokenSource
,将其分配给
ParallelOptions
的实例,在循环过程中,您可以根据需要触发它

public static void test()
{
    int Loop = 0;

    CancellationTokenSource cts = new CancellationTokenSource();

    try
    {
        Parallel.For(0, 2000, 
              new ParallelOptions() 
              { 
                  MaxDegreeOfParallelism = Environment.ProcessorCount, 
                 CancellationToken = cts.Token 
              }, 
        (i, End) =>
        {
            cts.Token.ThrowIfCancellationRequested();

            // ...

            if (i == 1000) // you should be using 'i'
            {
                Console.WriteLine("Break!");
                cts.Cancel();
            }
        });
    }
    catch (OperationCanceledException )
    {
        // expected behaviour
    }
}
正如General所说,您的循环不是线程安全的,因此我做了一些更改,并为您留下了一个空间

告诉我更多
另一种选择是使用方法。我已使用空控制台应用程序对其进行了测试:

Parallel.For(0, 2000, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount },
    (i, state) =>
    {
        Console.Write($"{i}, ");

        if (i == 1000)
        {
            Console.Write("STOP! ");
            state.Stop();
        }
    });
不受信任的输出为:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 1000, STOP! 580, 1500, 16,
结果与CancellationToken几乎相同,只是您不必处理
OperationCanceledException


还有一种方法。这有点不同。它停止循环的所有未来迭代的执行。因此,在本例中,停止后,您将不会看到任何超过1000的数字文本,但它们仍然可能出现在它前面。

循环
不是线程安全的,不能保证您的
写行
将按您认为的顺序打印,测试程序是毫无意义的,所有这些事实都让您很难得到帮助。@General抱歉,我很难解释这一点。
End.Stop()
不是也会这样吗?@vasily.sib我想会的,但是对于End.Stop(),它会一直运行,直到所有线程都碰到if语句。@vasily.sib我不确定。阅读doco给人的印象是,它将首先处理一批或其他东西。我一直使用上面的方法method@MickyD谢谢,但是当我添加
Loop++
控制台写入线(循环)在<>代码> //…<代码>结束时,我只剩下一个中断输出到控制台,但并行。for for循环仍在继续,它仍然将循环值输出到控制台。@ MICKYD是的,我想问另一个问题,而不是更好地适应情况。我真的不太使用stackoverflow,所以我应该在开始新的问题之前删除这个问题吗?很有趣。想知道它何时中止其他线程吗?立即的?分区会发生什么?从
控制台很难分辨。写
xxx。也许用datetime的另一种方式在其他地方登录+1@vasily.sib我只是尝试了
Stop()
而不是
Break()
,但他们都做了完全相同的事情,事情仍然很糟糕。@MickyD-这不会中止
.abort()
意义上的任何线程。@MickyD据我所知,它会在下一次迭代之前停止,所以如果有一个线程正在调用
state.Stop())
所有其他线程运行到其当前迭代的末尾(这就是为什么在
停止!
之后可以看到
580、1500、16、
)。@ArcticWolf\u 11将
if(Loop==1000)
替换为代码中的
if(i==1000)