2
代碼始終等待,直到OperationCancelledException
被引發之前當前正在運行的任務已完成。ParallelFor當條件滿足時不立即取消所有線程
我希望程序在條件成立時立即停止。
static void Main()
{
// want to break out of a Parallel.For immediately when a condition occurs
var cts = new CancellationTokenSource();
var po = new ParallelOptions();
po.CancellationToken = cts.Token;
long counterTotal = 0;
try
{
// want to have a sum of counts at the end
Parallel.For<long>(1, 26, po,() => 0, delegate(int i, ParallelLoopState state, long counterSubtotal)
{
po.CancellationToken.ThrowIfCancellationRequested();
Console.WriteLine(i.ToString());
for (int k = 0; k < 1000000000; k++)
{
counterSubtotal++;
if (i == 4 && k == 900000000)
{
cts.Cancel();
// Would like to break out here immediately
}
}
return counterSubtotal;
}, (x) => Interlocked.Add(ref counterTotal, x)
);
}
catch (OperationCanceledException e)
{
Console.WriteLine("Cancelled");
Console.WriteLine("Total iterations across all threads {0}", String.Format("{0:n0}", counterTotal));
Console.ReadLine();
}
}
我發現把一個斷點cts.Cancel()
和漁獲證明發生了什麼。
也看過state.Stop
。
這是其他代碼的簡化版本。
或許Parallel.For
對於那些在方法內部運行很久的東西,如果我們想要立即突破,可能不太理想。
UPDATE2: 代碼現在可以按預期並給出了一個很好的總
static void Main()
{
// want to break out of a Parallel.For immediately when a condition occurs
var cts = new CancellationTokenSource();
var po = new ParallelOptions();
po.CancellationToken = cts.Token;
long counterTotal = 0;
try
{
// want to have a sum of counts at the end
// using type param here to make counterSubtotal a long
Parallel.For<long>(1, 26, po,() => 0, delegate(int i, ParallelLoopState state, long counterSubtotal)
{
Console.WriteLine(i.ToString());
// 1 billion
for (int k = 0; k < 1000000000; k++)
{
//po.CancellationToken.ThrowIfCancellationRequested();
if (po.CancellationToken.IsCancellationRequested)
{
return counterSubtotal;
}
counterSubtotal++;
if (i == 4 && k == 400000000)
{
Console.WriteLine("Inner Cancelled");
cts.Cancel();
}
}
return counterSubtotal;
}, (x) => Interlocked.Add(ref counterTotal, x)
);
}
catch (OperationCanceledException e)
{
Console.WriteLine("Cancelled");
Console.WriteLine("Total iterations across all threads {0}", String.Format("{0:n0}", counterTotal));
Console.ReadLine();
}
}
謝謝pstrjds。請參閱上面我的代碼中的update2! – 2013-05-02 20:04:23