简体   繁体   中英

Pass Cancellation Token to child thread

I have scenario where I create a cancellation token that passed to parent thread, I need to pass same cancellation token to child thread. But when I pass cancellation token to child thread, threads are not cancelled when parent invokes 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);
    } 
}

I have created a cancellation token in parent class and passing it to child thread through parallel options, but threads created by Parallel.For are not terminated when parent invokes Cancel().

Is there a concept of passing CancellationToken as reference?

There's nothing inherently wrong with how you're using CancellationTokenSource. You just don't know that the task is cancelled because you're not using Wait to handle the TaskCanceledException . When Main is this:

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();

You would see the exceptions.

Here's a full example of Parallel.For being canceled:

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");
        }
    }
}

Output:

canceled

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM