liveBook · Manning

TaskCreationOptions.RunContinuationsAsynchronously

As explained in C# Concurrency: Asynchronous and multithreaded programming

RunContinuationsAsynchronously is a .NET task-creation option that causes task continuations to run asynchronously rather than inline during task completion.

TaskCreationOptions.RunContinuationsAsynchronously makes continuations run asynchronously instead of inline inside TaskCompletionSource completion calls. This prevents code after await or ContinueWith callbacks from executing while a lock is held. section 10.2 section 10.7

Use the option when:

  • A TrySetResult, TrySetException, or TrySetCanceled call occurs inside a lock. section 10.2
  • An asynchronous data structure must keep Enqueue and Dequeue operations fast and avoid running consumer code inside them. section 10.6
  • Completion may race with cancellation; prefer TrySetXXX methods because they report whether completion succeeded. section 10.6 section 10.7

Configure the TaskCompletionSource

var tcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); section 10.2

   public Task<T> Dequeue(CancellationToken cancellationToken)
  {
     lock (_lock)
     {
        if (_dataWaitingForProcessors.Count > 0)
        {
           return Task.FromResult(_dataWaitingForProcessors.Dequeue());
        }
        var tcs = new TaskCompletionSource<T>(
           TaskCreationOptions.RunContinuationsAsynchronously);
        _processorsWaitingForData.Enqueue(tcs);

An AsyncQueue creates its waiting TaskCompletionSource with the option while Dequeue holds its lock, then Enqueue completes waiting processors with TrySetResult. section 10.6

How C# Concurrency: Asynchronous and multithreaded programming covers it

How deep it goes
Explains runtime scheduling behavior, lock-related deadlocks, constructor configuration, and completion-method coverage.
Examples
Uses a locked value handoff and an AsyncQueue whose waiting processors receive data through completed tasks.
What it assumes
Assumes familiarity with TaskCompletionSource, await continuations, locks, and cancellation tokens.
What you can do after
Operate/configure TaskCompletionSource instances to defer continuations and safely complete tasks from locked code.
How it connects
Connects TaskCompletionSource with continuations, locks, cancellation, await, and asynchronous data structures.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of C# Concurrency: Asynchronous and multithreaded programming. The section links point to the parts of the book it draws on.