Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to transform task.Wait(CancellationToken) to an await statement?

So, task.Wait() can be transformed to await task. The semantics are different, of course, but this is roughly how I would go about transforming a blocking code with Waits to an asynchronous code with awaits.

My question is how to transform task.Wait(CancellationToken) to the respective await statement?

like image 307
mark Avatar asked Sep 02 '14 21:09

mark


People also ask

How do I wait for CancellationToken?

The CancellationTokenSource uses a ManualResetEvent internally and you can just wait for the exposed WaitHandle to pause the execution until it is set. var cts = new CancellationTokenSource(); Task. Run(() => { WaitHandle.

What is CancellationToken in C#?

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.

Which method can you use to cancel an ongoing operation that uses CancellationToken?

The CancellationToken is used in asynchronous task. The CancellationTokenSource token is used to signal that the Task should cancel itself. In the above case, the operation will just end when cancellation is requested via Cancel() method.

What does task Wait Do C#?

Wait(TimeSpan) is a synchronization method that causes the calling thread to wait for the current task instance to complete until one of the following occurs: The task completes successfully. The task itself is canceled or throws an exception.


1 Answers

await is used for asynchronous methods/delegates, which either accept a CancellationToken and so you should pass one when you call it (i.e. await Task.Delay(1000, cancellationToken)), or they don't and they can't really be canceled (e.g. waiting for an I/O result).

What you can do however, is abandon* these kinds of tasks with this extension method:

public static Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken)
{
    return task.IsCompleted // fast-path optimization
        ? task
        : task.ContinueWith(
            completedTask => completedTask.GetAwaiter().GetResult(),
            cancellationToken,
            TaskContinuationOptions.ExecuteSynchronously,
            TaskScheduler.Default);
}

Usage:

await task.WithCancellation(cancellationToken);

* The abandoned task doesn't get cancelled, but your code behaves as though it has. It either ends with a result/exception or it will stay alive forever.

like image 92
i3arnon Avatar answered Oct 10 '22 14:10

i3arnon