立即退出c#中的Parallel.For循环

时间:2013-02-06 01:21:08

标签: c# .net multithreading .net-4.0 parallel-processing

在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

有没有办法更快地完成这项工作? 谢谢!

2 个答案:

答案 0 :(得分:3)

是的,这可能。查看有关并行编程问题详细信息的this文章。以下是摘录:

  

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

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上的this文章,

  

在此上下文中,“break”表示完成所有线程上的所有迭代   在当前线程的当前迭代之前,和   然后退出循环。 “停止”表示尽快停止所有迭代   方便。

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

希望这能帮到你!

答案 1 :(得分:1)

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