【发布时间】:2016-01-22 13:31:04
【问题描述】:
我正在调用Parallel.Foreach() 中的一些代码。代码有Thread.Sleep(60000),所以如果我也取消令牌,那么它会在取消 Parallel.ForEach 循环之前等待 60 秒。
Thread.Sleep() 放在此代码中以进行解释。实际代码有一些等待其他资源的代码。
我想在调用cts.Cancel(); 时取消所有活动。
我也尝试了 LoopState,但在我的情况下它不起作用。
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
int[] nums = Enumerable.Range(0, 10000000).ToArray();
CancellationTokenSource cts = new CancellationTokenSource();
// Use ParallelOptions instance to store the CancellationToken
ParallelOptions po = new ParallelOptions();
po.CancellationToken = cts.Token;
po.MaxDegreeOfParallelism = System.Environment.ProcessorCount;
Console.WriteLine("Press any key to start. Press 'c' to cancel.");
Console.ReadKey();
// Run a task so that we can cancel from another thread.
Task.Factory.StartNew(() =>
{
if (Console.ReadKey().KeyChar == 'c')
{
cts.Cancel();
}
Console.WriteLine("press any key to exit");
});
try
{
Parallel.ForEach(nums, po, (num) =>
{
double d = Math.Sqrt(num);
Console.WriteLine("{0} on {1}", d, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(60000); //Thread Sleep for 1 minute
po.CancellationToken.ThrowIfCancellationRequested();
});
}
catch (OperationCanceledException e)
{
Console.WriteLine(e.Message);
}
finally
{
cts.Dispose();
}
Console.ReadKey();
}
}
【问题讨论】:
-
如果有人告诉你使用
Thread.Abort(),把他们赶走。 -
你基本上不能这样做,因为没有(理智的)方法来中断一些不参与合作取消的代码。通常你会让线程继续,但停止等待它(并忽略它的结果),但使用
Parallel.ForEach做到这一点并不容易 -
"如果 main() 的所有代码都在一个线程下运行..." 但事实并非如此。你刚刚打电话给
Parallel.ForEach()。无论如何,read this。正如 Eric Lippert 所说:Thread.Abort 充其量是糟糕设计的表现,可能不可靠,而且极其危险。应该不惜一切代价避免它 -
无论如何,如果您有一些代码正在等待其他资源,您应该更改它,以便在等待时允许合作取消。
-
@RomilKumarJain - 你在用什么
IndexOf需要这么长时间?也许你的那部分代码需要一些优化?
标签: c# .net multithreading parallel-processing