1

在 C# 中,是否可以立即退出正在进行的 Parallel.For 循环。在调用 loopState.Stop() 之后,以下代码可能需要一整秒才能退出循环。

static void Main(string[] args)
{
    Stopwatch watch = new Stopwatch();

    Parallel.For(0, 50, (i, loopState) =>
    {
        Console.WriteLine("Thread:" + Thread.CurrentThread.ManagedThreadId + "\tIteration:" + i);
        Thread.Sleep(1000);

        if (i == 0)
        {
            watch.Start();
            loopState.Stop();
            return;
        }
    });

    Console.WriteLine("Time Elapsed since loopState.Stop(): {0}s", watch.Elapsed.TotalSeconds);
    Console.ReadKey();
}

输出

Thread:10       Iteration:0
Thread:6        Iteration:12
Thread:11       Iteration:24
Thread:12       Iteration:36
Thread:13       Iteration:48
Thread:13       Iteration:49
Thread:12       Iteration:37
Time Elapsed since loopState.Stop(): 0.9999363s

有什么办法可以更快地做到这一点?谢谢!

4

2 回答 2

3

是的,这可能。查看这篇详细介绍并行编程问题的文章。以下是其中的摘录:

如果我不想浪费资源并想在单击取消后立即停止所有计算怎么办?在这种情况下,我必须定期检查执行长时间运行操作的方法中某处的取消令牌的状态。由于我将取消标记声明为一个字段,因此我可以在方法中简单地使用它。

public double SumRootN(int root)
{
    double result = 0;
    for (int i = 1; i < 10000000; i++)
    {
        tokenSource.Token.ThrowIfCancellationRequested();
        result += Math.Exp(Math.Log(i) / root);
    }
    return result;
}

使用传统的StopBreak不会导致任务立即取消,正如您所经历的那样。根据MSDN 上的这篇文章,

在此上下文中,“中断”表示在当前线程上完成当前迭代之前的所有线程上的所有迭代,然后退出循环。“停止”意味着在方便的时候停止所有的迭代。

所以你不能用传统的方法强制它立即停止。您将需要使用我在开头提到的方法。

希望这对你有帮助!

于 2013-02-06T01:26:47.467 回答
1

问题是循环体的运行时间。 loopState.Stop()从头开始停止任何新的循环迭代,并等待当前正在运行的任何循环完成。

于 2013-02-06T01:29:08.770 回答