.net 在parallel.foreach上迭代时,我可以只取消一个线程吗?
当我使用parallel.foreach时,有没有办法取消一个特定的线程 我知道我可以使用cancelToken.token使用parallelOptions取消所有线程,但如何取消一个特定线程.net 在parallel.foreach上迭代时,我可以只取消一个线程吗?,.net,multithreading,parallel-processing,parallel.foreach,.net,Multithreading,Parallel Processing,Parallel.foreach,当我使用parallel.foreach时,有没有办法取消一个特定的线程 我知道我可以使用cancelToken.token使用parallelOptions取消所有线程,但如何取消一个特定线程 我知道,如果我创建的是线程列表而不是parallel.foreach,那么选择要取消的线程是没有问题的,但我希望我的程序以并行顺序运行,而不仅仅是异步运行,因为我希望使用所有CPU,而不仅仅是分割CPU资源。我想说清楚,并行类使用队列来排队和执行工作 为了回答你的问题,我不认为有一种方法可以取消一个特定
我知道,如果我创建的是线程列表而不是parallel.foreach,那么选择要取消的线程是没有问题的,但我希望我的程序以并行顺序运行,而不仅仅是异步运行,因为我希望使用所有CPU,而不仅仅是分割CPU资源。我想说清楚,并行类使用队列来排队和执行工作 为了回答你的问题,我不认为有一种方法可以取消一个特定的线程本身,但是你可以中断并行。因为不使用取消令牌
请参阅MSDN上的以下内容:如何:。为了清楚起见,并行类使用来排队和执行工作 为了回答你的问题,我不认为有一种方法可以取消一个特定的线程本身,但是你可以中断并行。因为不使用取消令牌
请参见MSDN上的以下内容:如何:。编辑:好的,所以我的第一个想法很糟糕,但这是可行的:
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编辑:好的,所以我的第一个想法很糟糕,但这很有效:
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如前所述,如果您使用Parallel.Foreach或Parallel.for,那么线程池将用于执行代码
为什么不使用Task编写一些类似的功能,但要记住这样的取消
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());
这就是您试图实现的目标吗?如前所述,如果您使用Parallel.Foreach或Parallel.For,那么将使用ThreadPool来执行代码
为什么不使用Task编写一些类似的功能,但要记住这样的取消
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());
这就是你想要达到的目标吗?你能解释一下你真正想要达到的目标是什么吗?您想停止线程还是循环的迭代?如果它真的是一根线,为什么?Parallel.ForEach主要为您管理线程,您不需要做任何类似的事情。您能解释一下您实际上想要完成什么吗?您想停止线程还是循环的迭代?如果它真的是一根线,为什么?Parallel.ForEach主要为您管理线程,您不需要执行类似的操作。不,您不能在Parallel.ForEach中使用continue。等价物只是调用return;或返回本地;从body函数开始,这取决于您是否使用了或。谢谢,我在启动VS并记住Parallel.ForEach的签名中有一个委托时就得到了它。很抱歉方向错误。不,您不能使用并行的continue.foreach。等价物只是调用return;或返回本地;从body函数开始,这取决于您是否使用了或。谢谢,我在启动VS并记住Parallel.ForEach的签名中有一个委托时就得到了它。对不起,误会了。