我有一个场景,我创建一个传递给父线程的取消令牌,我需要将相同的取消令牌传递给子线程。但是当我将取消令牌传递给子线程时,当父调用Cancel()时,线程不会被取消。
public void main()
{
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
ChildClass instance = new ChildClass();
Task.Factory.StartNew(() =>
Task.Factory.StartNew(() => instance.start(token), token), token);
}
public void cancel()
{
cts.Cancel();
}
public class ChildClass()
{
public void start(CancellationToken token)
{
ParallelOptions po = new ParallelOptions();
po.CancellationToken = token;
Parallel.For(0, 10, i =>
{"do some processing"}, po, i);
}
}
我在父类中创建了一个取消令牌,并通过并行选项将其传递给子线程,但是当父调用Cancel()时,Parallel.For创建的线程不会终止。
是否存在将CancellationToken作为参考传递的概念?
答案 0 :(得分:1)
您使用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();
你会看到例外情况。
以下是Parallel.For
被取消的完整示例:
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");
}
}
}
输出:
取消