liveBook · Manning

Task.ContinueWith

As explained in C# Concurrency: Asynchronous and multithreaded programming

A .NET Task method that creates a continuation to run after the task completes, fails, or is canceled.

Task.ContinueWith attaches a callback that runs after a Task completes, faults, or is canceled. The callback receives the completed Task, allowing code to inspect its state and, for Task<T>, read its result. section 3.2.2 section 3.2.4

Use the continuation model deliberately:

  • Check IsCompletedSuccessfully before consuming a successful result; reading Result before completion blocks, while reading it after a fault or cancellation throws. section 3.2.2 section 3.2.4
  • Handle failures through the completed task’s exception; faulted tasks expose an AggregateException containing the original exception in InnerExceptions. section 3.2.4
  • Chain continuations only when necessary: each asynchronous step moves logic farther right, reduces readability, and complicates returning results, throwing exceptions, and disposing resources. section 3.2.2 section 3.3
  • Remember that a ContinueWith callback runs on the thread pool, not automatically on a UI thread; marshal UI updates with BeginInvoke or Dispatcher.BeginInvoke. section 11.1.1

Reading a file asynchronously

A continuation can process bytes after File.ReadAllBytesAsync completes: `var readCompleted = File.ReadAllBytesAsync("example.bin"); readCompleted.ContinueWith(t => { if (t.IsCompletedSuccessfully) { byte[] bytes = t.Result; /* process bytes */ } });` For multi-step file parsing, equivalent nested continuations require explicit state, cleanup, callbacks, and exception propagation, whereas async/await expresses the same sequence more directly.

Listing 11.3 UI access with ContinueWith
private void button1_Click(object sender, EventArgs ea)
{
   var result = DoSomething(textBox1.Text).ContinueWith(t=>
   {
      label1.BeginInvoke((Action)(()=>                       #1
      { 
          label1.Text = t.Result));
      });
   }
}

Inspect the UI-safe continuation pattern that marshals result handling back to the UI thread with BeginInvoke. section 11.1.1

How C# Concurrency: Asynchronous and multithreaded programming covers it

How deep it goes
Explains callback state, results, exceptions, chaining, cleanup, and thread affinity, then defers clearer sequencing to async/await.
Examples
Demonstrates asynchronous BMP parsing, nested one-byte file reads, UI updates, and explicit exception and resource handling.
What it assumes
Assumes familiarity with Task and Task<T>, while establishing completion states, Result access, exception behavior, and asynchronous control flow.
What you can do after
Apply it via C# callbacks that inspect completion, consume results, handle failures, and marshal UI work safely.
How it connects
Connects Task, Task<T>, asynchronous file I/O, async/await, AggregateException, thread pools, and UI-thread marshaling.

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.