Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why pass cancellation token to TaskFactory.StartNew?

Besides the most common form of calling TaskFactory.StartNew with only the "action" parameter (1) https://msdn.microsoft.com/en-us/library/dd321439(v=vs.110).aspx

we alse have one method that accepts an extra parameter as the "Cancelation Token" (2) https://msdn.microsoft.com/en-us/library/dd988458.aspx

My question is, why should we use the call (2) instead of call (1)?

I mean, the example in MSDN for page (2) would also work if I don't pass the Cancellation Token as parameter (because the variable token is accessible from the delegate function. Something like:

var tokenSource = new CancellationTokenSource();
      var token = tokenSource.Token;
      var files = new List<Tuple<string, string, long, DateTime>>();

      var t = Task.Factory.StartNew( () => { string dir = "C:\\Windows\\System32\\";
                                object obj = new Object();
                                if (Directory.Exists(dir)) {
                                   Parallel.ForEach(Directory.GetFiles(dir),
                                   f => {
                                           if (token.IsCancellationRequested)
                                              token.ThrowIfCancellationRequested();
                                           var fi = new FileInfo(f);
                                           lock(obj) {
                                              files.Add(Tuple.Create(fi.Name, fi.DirectoryName, fi.Length, fi.LastWriteTimeUtc));          
                                           }
                                      });
                                 }
                              }
                        ); //note that I removed the ", token" from here
      tokenSource.Cancel();

So is there anything happening underneath when I pass cancellation token to Task.Factory.StartNew?

Thanks

like image 381
Zé Carlos Avatar asked Mar 21 '16 15:03

Zé Carlos


People also ask

What is the purpose of cancellation token?

A CancellationToken enables cooperative cancellation between threads, thread pool work items, or Task objects. You create a cancellation token by instantiating a CancellationTokenSource object, which manages cancellation tokens retrieved from its CancellationTokenSource.

What is task factory StartNew?

StartNew(Action<Object>, Object, CancellationToken, TaskCreationOptions, TaskScheduler) Creates and starts a task for the specified action delegate, state, cancellation token, creation options and task scheduler.


1 Answers

Two things will happen.

  1. If the token has been canceled before StartNew is called it will never start the thread and the task will be in the Canceled state.
  2. If a OperationCanceledException is raised from inside the task and that exception was passed in the same token as StartNew it will cause the returned Task to enter the Cancelled state. If the token associated with the exception is a different token or you did not pass a token in the task will enter the Faulted state.

P.S. You should never call Task.Factory.StartNew without passing in a TaskScheduler because if you don't it can easily cause you to run code on the UI thread that you expected to run on a background thread. Use Task.Run( instead unless you absoultely need to use StartNew, Task.Run has the same CancellationToken behavior as StartNew.

like image 184
Scott Chamberlain Avatar answered Sep 22 '22 22:09

Scott Chamberlain