在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
有没有办法更快地完成这项工作? 谢谢!
答案 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;
}
使用传统的Stop
或Break
不会导致任务立即取消,正如您所遇到的那样。根据MSDN上的this文章,
在此上下文中,“break”表示完成所有线程上的所有迭代 在当前线程的当前迭代之前,和 然后退出循环。 “停止”表示尽快停止所有迭代 方便。
所以你不能强迫它立即使用传统方法停止。您将需要使用我在开头提到的方法。
希望这能帮到你!
答案 1 :(得分:1)
问题是循环体的运行时间。 loopState.Stop()
从开始就停止任何新的循环迭代,并等待当前正在运行的任何迭代完成。