如何立即终止 Parallel.ForEach 线程
本文关键字:ForEach 线程 Parallel 终止 何立即 | 更新日期: 2023-09-27 18:31:24
我正在Parallel.Foreach()
调用一些代码。代码有Thread.Sleep(60000)
,所以如果我也取消令牌,那么它会等待 60 秒,然后再取消 Parallel.ForEach 循环。 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();
}
}
如果我理解正确,并不是您需要立即中断线程,而是您只是希望在等待时能够中断Sleep()
方法。
有许多选项,但恕我直言,最简单的选项之一是使用 CancellationToken.WaitHandle
属性值,然后等待该值而不是睡眠:
po.CancellationToken.WaitHandle.WaitOne(60000);
如果令牌发出信号,则 Wait()
方法将在指定的超时(在本例中为一分钟)之前返回。
通常你会检查返回值,这样你就可以分辨出发出信号的句柄和等待超时之间的区别,但在你的情况下,你会立即调用po.CancellationToken.ThrowIfCancellationRequested();
,所以在我看来,忽略Wait()
方法的返回值并让下一个程序语句负责实际中断方法似乎是合理的。