当我使用parallel.foreach
时,有没有办法取消一个特定的帖子?
我知道我可以使用cancelToken.token
使用parallelOptions()
取消所有主题,但如何取消一个特定主题?
我知道如果我创建一个线程列表而不是parallel.foreach
,那么选择要取消的线程没有问题,但我希望我的程序以并行顺序运行而不仅仅是异步(因为我想要使用我所有的CPU,而不仅仅是切断CPU资源。)
答案 0 :(得分:3)
编辑:好的,所以我的第一个想法很糟糕,但这很有效:
List<string> Items = new List<string>()
{
"First",
"Second",
"Third",
"Fourth"
};
Parallel.ForEach(Items, (s, t) =>
{
if (s == "Second")
return;
Console.WriteLine(s);
});
我想这将教会我在不等待Visual Studio的情况下发布答案,从中吸取教训:P
答案 1 :(得分:2)
正如William Xifaras已经提到过,如果您使用Parallel.Foreach
或Parallel.For
,那么ThreadPool
将用于执行您的代码。
为什么不使用Task<T>
来编写类似的功能,但请记住这样的取消。
Action<CancellationToken> work = (token) =>
{
Console.WriteLine($"Work started on Thread: {Thread.CurrentThread.ManagedThreadId}");
foreach (var i in Enumerable.Range(0, 10))
{
if (token.IsCancellationRequested)
{
Console.WriteLine($"Work cancelled on Thread: {Thread.CurrentThread.ManagedThreadId}");
return;
}
Thread.Sleep(1000);
}
Console.WriteLine($"Work complete on Thread: {Thread.CurrentThread.ManagedThreadId}");
};
var tasks = new List<Tuple<Task, CancellationTokenSource>>();
foreach (var i in Enumerable.Range(0, 4))
{
var cancellation = new CancellationTokenSource();
var task = Task.Run(() => work(cancellation.Token), cancellation.Token);
tasks.Add(new Tuple<Task, CancellationTokenSource>(task, cancellation));
}
tasks.First().Item2.Cancel();
Task.WaitAll(tasks.Select(m => m.Item1).ToArray());
这将产生类似的输出:
Work started on Thread: 3
Work started on Thread: 6
Work started on Thread: 4
Work started on Thread: 5
Work cancelled on Thread: 3
Work complete on Thread: 6
Work complete on Thread: 5
Work complete on Thread: 4
这是你试图实现的目标吗?
答案 2 :(得分:1)
为了清楚起见,Parallel类使用ThreadPool来排队并执行工作。
要回答您的问题,我认为您无法取消特定的“线程”本身,但是您可以在不使用取消令牌的情况下从Parallel.For中断。
请参阅MSDN上的以下内容:如何:Stop or Break from a Parallel.For Loop。