C# 将取消令牌传递给子线程
我有一个场景,我创建了一个传递给父线程的取消令牌,我需要将相同的取消令牌传递给子线程。但当我将取消令牌传递给子线程时,当父线程调用Cancel()时,线程不会被取消 我在父类中创建了一个取消令牌,并通过parallel选项将其传递给子线程,但由parallel.For创建的线程在父类调用Cancel()时不会终止C# 将取消令牌传递给子线程,c#,task-parallel-library,parallel.for,C#,Task Parallel Library,Parallel.for,我有一个场景,我创建了一个传递给父线程的取消令牌,我需要将相同的取消令牌传递给子线程。但当我将取消令牌传递给子线程时,当父线程调用Cancel()时,线程不会被取消 我在父类中创建了一个取消令牌,并通过parallel选项将其传递给子线程,但由parallel.For创建的线程在父类调用Cancel()时不会终止 是否有将CancellationToken作为参考传递的概念?您使用CancellationTokenSource的方式没有本质上的错误。您只是不知道任务已取消,因为您没有使用Wait
是否有将CancellationToken作为参考传递的概念?您使用CancellationTokenSource的方式没有本质上的错误。您只是不知道任务已取消,因为您没有使用
Wait
来处理TaskCanceledException
。当Main
是:
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
ChildClass instance = new ChildClass();
var task = Task.Factory.StartNew(() =>
Task.Factory.StartNew(() => instance.start(token), token), token);
cts.Cancel();
task.Wait();
你会看到例外情况
以下是并行的完整示例。对于被取消的:
internal class Program
{
private static void Main()
{
var cts = new CancellationTokenSource();
var instance = new ChildClass();
var task = Task.Factory.StartNew(() =>
Task.Factory.StartNew(() => instance.start(cts.Token)).Wait());
cts.Cancel();
task.Wait();
}
}
public class ChildClass
{
public void start(CancellationToken token)
{
var parallelOptions = new ParallelOptions {CancellationToken = token};
try
{
Parallel.For(0, 100000, parallelOptions, i =>
{
// Do something
});
}
catch (OperationCanceledException)
{
Console.WriteLine("canceled");
}
}
}
输出:
取消
您在哪里调用Cancel()?ChildClass
是类还是方法?添加了调用cancel()的代码段,这是一个windows服务,因此从系统接收取消事件时将调用cancel()方法。ChildClass是一个类。如果(token.IsCancellationRequested==true)…我想说,从v4.0开始,传递CancellationTokenSource是线程编程的一个基本概念。如果您发现闭包不能与Parallel.For()
一起使用,我想知道,这是因为您没有评估令牌.IsCancellationRequested
?我也没有在您的示例代码中看到任何标记。ThrowIfCancellationRequested
。我尝试了task.WaitAll(),但是由Parallel.For创建的子线程没有被取消。@VarunGupta是的,我添加了一个完整的示例。是的,这很有效,谢谢您的回复。我面临的问题是,我有一个windows服务,在OnStop方法中,我调用cts.Cancel()。这是不调用OperationCancelledException,有什么原因吗?@VarunGupta要么操作实际上已经结束,代码卡在其他东西上,要么存在异常,但它在一个任务中,您不等待/等待。我以前遇到过一个问题,但在调用OnStop方法中的cts.Cancel()后使用task.wait()之后,问题已解决。:)
internal class Program
{
private static void Main()
{
var cts = new CancellationTokenSource();
var instance = new ChildClass();
var task = Task.Factory.StartNew(() =>
Task.Factory.StartNew(() => instance.start(cts.Token)).Wait());
cts.Cancel();
task.Wait();
}
}
public class ChildClass
{
public void start(CancellationToken token)
{
var parallelOptions = new ParallelOptions {CancellationToken = token};
try
{
Parallel.For(0, 100000, parallelOptions, i =>
{
// Do something
});
}
catch (OperationCanceledException)
{
Console.WriteLine("canceled");
}
}
}