πŸ“œ ⬆️ ⬇️

Tasks and cancellation in .Net - tips & tricks

With the release of the .NET Framework 4.0, Task Parallel Library (TPL) has been added to BCL to implement task-based parallelism. The library is based on the Task types and the Task type inherited from it . These types are wrappers for asynchronous operations; they allow to abstract from such technical details as, for example, flows and to synchronize asynchronous operations with each other.

In the same version of the .NET Framework, a mini-framework appeared for cooperative undoing asynchronous operations. It consists of only three types:

The cancellation mechanism via the CancellationToken is standard for the TPL β€” there are overloads of methods that accept CancellationToken , exceptions OperationCanceledException are handled in a special way, etc. However, as in any other API, there are subtleties, tricks, best practices.

Why is co-operative cancellation?


The code that performs an asynchronous operation can be divided into three parts (layers):

The cancellation mechanism through the CancellationToken is cooperative, because it requires the coordinated support of the cancellation functionality from all three layers. A typical code that performs an asynchronous operation with support for cancellation looks like this:
 CancellationTokenSource cts; void Start() { cts = new CancellationTokenSource(); //    var task = Task.Run(() => SomeWork(cts.Token), cts.Token); //     // // ... } int SomeWork(CancellationToken cancellationToken) { int result; while (true) { // -  ... // ...   ,      cancellationToken.ThrowIfCancellationRequested(); } //   return result; } void Cancel() { //    cts.Cancel(); } 

In this example, the code in the Start and Cancel functions is the outer layer. It initiates an asynchronous operation by calling the Task.Run method. In doing so, he passes the CancellationToken into two places at once: into the inner layer that directly performs the operation (the SomeWork method) and into the infrastructure layer (the second argument of the Task.Run function). The Cancel function requests that the operation be canceled.

The inner layer (the SomeWork function) besides executing the payload periodically checks whether cancellation is requested and, if necessary, throws an OperationCanceledException exception indicating that the cancellation request has been processed.
')
The infrastructure layer (inside the TPL) to support cancellation does two things. First, before launching the function passed to Task.Run , it checks whether cancellation is requested. If so, the function does not even run. Secondly, it handles in a special way the exception OperationCanceledException , informing about the cancellation of the operation.

Cancel request processing


After calling the CancellationTokenSource.Cancel method (or after the timeout specified when calling the CancellationTokenSource constructor / CancellationTokenSource.CancelAfter method has been called), the CancellationTokenSource.CancelAfter object changes to the canceled state. The transition to the canceled state can occur exactly once. It is impossible to change your mind and make a canceled CancellationTokenSource not canceled, and repeated calls to Cancel ignored.

Calling functions that are registered via the CancellationToken.Register method are called when switching to the canceled state, the CancellationToken.Register property starts returning true , and a call to the CancellationToken.ThrowIfCancellationRequested method will generate an OperationCanceledException exception.

The inner layer code should periodically check for a cancel request. Typically, the verification code is reduced to calling the ThrowIfCancellationRequested method if the operation can be interrupted immediately. If you need to perform additional actions before IsCancellationRequested (for example, release used resources), then the verification code refers to the IsCancellationRequested property. If it is true , the resource is cleared and an OperationCanceledException exception is thrown (again, by calling the ThrowIfCancellationRequested method or manually).

Here it is important to pay attention to the following. First, if the cancellation request is not handled by the opcode, the operation will continue. In the end, when the operation is completed (normally or with an exception), the task will be completed ( Task.IsCompleted == true ), but it will not be considered canceled ( Task.IsCanceled == false ).

Secondly, you need to choose the optimal size of the interval between checks. If the interval is too large, the operation will do the extra work if canceled. If the interval is too small - the overhead of the test will increase the time of the operation. It is difficult to recommend any specific values, much depends on the specific scenario. General recommendations are as follows: if the probability of cancellation is not very high, checks can be performed less frequently. If the cancellation of the operation is initiated by the user, to ensure the responsiveness of the UI, it is sufficient to check every 200-250 ms. If the operation is performed in the server application, checks should be performed more often, so that in case of cancellation, do not waste server resources. Checks should not take more than a few percent of the total operation time. Again, I repeat that these are just general recommendations and in each specific case the developer must make a decision himself taking into account all the influencing factors. Perhaps not superfluous will be the help of the profiler.

Third, the CancellationToken has a CanBeCanceled property. If it returns false , the cancellation request is guaranteed not to be and checks can be omitted. CanBeCanceled is false if the CancellationToken received using the static CancellationToken.None property or created by the default constructor or constructor with the parameter set to false .

And finally, fourthly, in order for the task to be performed, which was created β€œmanually” (not by the async method), correctly canceled (so that the Task.IsCanceled property returns true ), the following is necessary:

Consider examples:
 var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; //... Task.Run(() => { //... if (cancellationToken.IsCancellationRequested) throw new OperationCanceledException(); //   CancellationToken //... }, cancellationToken); 

Here the CancellationToken not passed to the OperationCanceledException constructor. That is why it is preferable to use the CancellationToken.ThrowIfCancelationRequested method and not to generate an OperationCanceledException manually.

 var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; //... Task.Run(() => { //... cancellationToken.ThrowIfCancellationRequested(); //... }/*   CancellationToken */); 

In this example, when creating a task, the Task.Run not passed to the Task.Run method.

 var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; var cts2 = new CancellationTokenSource(); var cancellationToken2 = cts2.Token; //... var task = Task.Run(() => { //... cancellationToken2.ThrowIfCancellationRequested(); // «» CancellationToken //... }, cancellationToken); 

Here, to create a task and to cancel, CancellationToken are used, obtained from various CancellationTokenSource 's.

 var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; //... var task = Task.Run(() => { //... if (!cancellationToken.IsCancellationRequested) //    throw new OperationCanceledException(cancellationToken); //... }, cancellationToken); 

An OperationCanceledException generated here, although no cancellation was requested.

In all examples, an OperationCanceledException exception will be treated inside the TPL not as a cancel signal, but as a normal exception. As a result, the task will not end with the cancellation, but with an error ( Task.IsCancelled == false , Task.IsFaulted == true ).

Cancellation and continuation tasks


TPL allows you to chain tasks using the overloaded Task.ContinueWith method. The task created by the Task.ContinueWith method is called the continuation task, and the task for which the method was called is the predecessor task. The continuation task waits for the completion of the predecessor task, and then it executes
 var antecedentTask = Task.Run(() => Console.Write("Hello, ")); var continuationTask = antecedentTask.ContinueWith(_ => Console.Write("world!")); //    `Hello, world!` 

Continuation tasks fully support cancellation and everything that was written above applies to them. The Task.ContinueWith method has overloads that allow you to associate with the created task CancellationToken .

If the cancellation request comes when the continuation task has not yet started to be executed, it will not be executed. In this case, by default, the continuation task will be canceled immediately and may be completed earlier than the predecessor task:
 var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; var antecedentTask = Task.Run(() => Thread.Sleep(5000)); var continuationTask = antecedentTask.ContinueWith( _ => {}, cancellationToken); Thread.Sleep(1000); cts.Cancel(); Console.WriteLine(antecedentTask.IsCompleted); // False Console.WriteLine(continuationTask.IsCompleted); // True 

But you can change this behavior if you create a continuation task using the TaskContinuationOptions.LazyCancellation flag TaskContinuationOptions.LazyCancellation specify that a lazy cancellation is required. In this case, the continuation task will not be canceled (and will not end) until the predecessor task is completed:
 var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; var antecedentTask = Task.Run(() => Thread.Sleep(5000)); var continuationTask = antecedentTask.ContinueWith( _ => {}, cancellationToken, TaskContinuationOptions.LazyCancellation, TaskScheduler.Default); Thread.Sleep(1000); cts.Cancel(); Console.WriteLine(antecedentTask.IsCompleted); // False Console.WriteLine(continuationTask.IsCompleted); // False 

Of particular interest is the case when the continuation task can become canceled without using CancellationToken . In TaskContinuationOptions there are a number of flags that allow you to specify in which cases the continuation task should be launched. For example, for the predecessor task, you can create two continuation tasks β€” one for the case when the predecessor task completes normally, the second for the case when an error / cancellation occurs in the predecessor task. After the completion of the predecessor task, only one of the continuation tasks will start, and the second will be canceled:
 var antecedentTask = Task.Run(() => {}); var continuationTask1 = antecedentTask.ContinueWith( _ => {}, TaskContinuationOptions.OnlyOnRanToCompletion); var continuationTask2 = antecedentTask.ContinueWith( _ => {}, TaskContinuationOptions.NotOnRanToCompletion); try { Task.WaitAll(continuationTask1, continuationTask2); } catch{} Console.WriteLine(continuationTask1.IsCanceled); // False Console.WriteLine(continuationTask2.IsCanceled); // True 

Cancel and async methods


In C # 5.0, async methods appeared . From the point of view of cancellation, async methods are interesting in that only void and Task / Task. , async- (Task / Task), , . ,
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
types can be used as return values Task. , async- (Task / Task), , . ,
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
Task. , async- (Task / Task), , . ,
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
 Task.   ,  async-   (Task / Task),    ,   . ,   
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
Task. , async- (Task / Task), , . ,
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
 Task.   ,  async-   (Task / Task),    ,   . ,   
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
Task. , async- (Task / Task), , . ,
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
 Task.   ,  async-   (Task / Task),    ,   . ,   
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
Task. , async- (Task / Task), , . ,
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
 Task.   ,  async-   (Task / Task),    ,   . ,   
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
Task. , async- (Task / Task), , . ,
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
Task. , async- (Task / Task), , . ,
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
 Task.   ,  async-   (Task / Task),    ,   . ,   
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
Task. , async- (Task / Task), , . ,
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }

Task. , async- (Task / Task), , . ,
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }

Task. , async- (Task / Task), , . ,
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
 Task.   ,  async-   (Task / Task),    ,   . ,   
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
Task. , async- (Task / Task), , . ,
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
 Task.   ,  async-   (Task / Task),    ,   . ,   
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
Task. , async- (Task / Task), , . ,
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }
 Task.   ,  async-   (Task / Task),    ,   . ,   
Task<int> task = Task .Delay(TimeSpan.FromSeconds(5)) .ContinueWith(_ => { while (true) { // - } return 42; });

async- :
Task<int> task = SomeWork(); async Task<int> SomeWork() { await Task.Delay(TimeSpan.FromSeconds(5)); while (true) { // - } return 42; }
, Task.Run , Task.Factory.StartNew , . SomeWork int . , SomeWork Task.

, async-, , , . , :
var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = Task .Delay(TimeSpan.FromSeconds(5), cancellationToken) .ContinueWith(_ => { while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }, cancellationToken);


var cts = new CancellationTokenSource(); var cancellationToken = cts.Token; Task<int> task = SomeWork(cancellationToken); async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); /* 1 */ await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); /* 2 */ while (true) { // - cancellationToken.ThrowIfCancellationRequested(); } return 42; }
, async-, , CancellationToken ( CancellationToken async- CancellationToken ). :
async-, async- . (, Task.Run Task.ContinueWith ) . 1 2. , async-, . OperationCanceledException . CancellationToken , , .. . , , CancellationToken . , Task.Run , :
static async Task<int> SomeWork(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); throw new OperationCanceledException(cancellationToken); throw new OperationCanceledException(); throw new OperationCanceledException(CancellationToken.None); throw new OperationCanceledException(new CancellationToken(true)); throw new OperationCanceledException(new CancellationToken(false)); }

Task.IsCompleted true . ( Task.Status == TaskStatus.RanToCompletion ), ( Task.Status == TaskStatus.Faulted ; Task.IsFaulted == true ) ( Task.Status == TaskStatus.Canceled ; Task.IsCanceled == true ). .

-. TaskContinuationOptions - -:
var task = Task.Run(() => 42); task.ContinueWith( t => Console.WriteLine("Result: {0}", t.Result), TaskContinuationOptions.OnlyOnRanToCompletion); task.ContinueWith( _ => Console.WriteLine("Canceled"), TaskContinuationOptions.OnlyOnCanceled); task.ContinueWith( t => Console.WriteLine("Error: {0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted);
Task.Wait Task.Result. c , . . -, β€” AggregateException . AggregateException , ( AggregateException ). -, , , AggregateException TaskCanceledException , OperationCanceledException , :
var task = Task.Run(() => { /* - */ }); try { task.Wait(); Console.WriteLine("Success"); } catch (AggregateException ae) { try { ae.Flatten().Handle(e => e is TaskCanceledException); Console.WriteLine("Cancelled"); } catch (AggregateException e) { Console.WriteLine("Error: {0}", e); } }
async- await . AggregateException , OperationCanceledException ; :
var task = Task.Run(() => { /* - */ }); try { await task; Console.WriteLine("Success"); } catch (OperationCanceledException) { Console.WriteLine("Cancelled"); } catch (Exception e) { Console.WriteLine("Error: {0}", e); }

Source: https://habr.com/ru/post/168669/


All Articles