当一个线程与if语句匹配时,如何摆脱Parallel.For循环?

时间:2018-11-02 05:02:48

标签: c# parallel-processing

所以在我的program中,我希望在控制台中显示完成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语句匹配时如何使它停止在一起。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:4)

Parallel.Forxxx支持CancellationToken。只需创建一个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
    }
}

正如 TheGeneral 所说,您的循环不是线程安全的,因此我进行了一些更改并留出空间供您填充。

告诉我更多

答案 1 :(得分:4)

另一种选择是使用ParallelLoopState.Stop()方法。我已经用空的控制台应用程序对其进行了测试:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="error-msg"></div>
<br><br>

<form>
  <div class="form-group">
    <label>OLD PASSWORD</label>
    <input type="password" id="old-password" class="form-control">
  </div>
  <div class="form-group">
    <label>NEW PASSWORD</label>
    <input type="password" id="password1" class="form-control">
  </div>
  <div class="form-group">
    <label>CONFIRM PASSWORD</label>
    <input type="password" id="password2" class="form-control">
  </div>
</form>
<button type="button" id="submitBtn" class="btn btn-primary">UPDATE</button>

未截断的输出为:

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

        if (i == 1000)
        {
            Console.Write("STOP! ");
            state.Stop();
        }
    });

与CancellationToken几乎相同的结果,除了您不必处理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,

还有一种ParallelLoopState.Break()方法。哪有一点不同。它停止执行循环的所有未来迭代。因此,在这种情况下,您看到的数字不会超过{strong> OperationCanceledException之后的 1000个数字,但是它们前面可能仍然存在。