๐ŸŽ“ A1Learner
๐Ÿ”
0 of 28 lessons completed

C# ConfigureAwait

ConfigureAwait(false) tells an await not to resume on the context it captured. The continuation then runs on a thread pool thread instead.

One configured await

Fetch awaits a task with ConfigureAwait(false) and returns a string. Main prints the result and then its own line.

using System;
using System.Threading.Tasks;

class Program
{
    static async Task<string> Fetch()
    {
        await Task.Delay(1).ConfigureAwait(false);
        return "data";
    }

    static async Task Main(string[] args)
    {
        string result = await Fetch();
        Console.WriteLine(result);
        Console.WriteLine("Done");
    }
}

Plain and configured side by side

One method holds a plain await and a configured await. Both complete in order and the lines print in program order.

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Run()
    {
        await Task.CompletedTask;
        Console.WriteLine("A");
        await Task.Delay(1).ConfigureAwait(false);
        Console.WriteLine("B");
    }

    static async Task Main(string[] args)
    {
        await Run();
    }
}

A chain of helpers

Outer awaits Inner with ConfigureAwait(false) and Inner configures its own await too. The value travels back up the chain.

using System;
using System.Threading.Tasks;

class Program
{
    static async Task<int> Inner()
    {
        await Task.Delay(1).ConfigureAwait(false);
        return 42;
    }

    static async Task<int> Outer()
    {
        int value = await Inner().ConfigureAwait(false);
        return value;
    }

    static async Task Main(string[] args)
    {
        Console.WriteLine(await Outer());
    }
}

Example

using System;
using System.Threading.Tasks;

class Program
{
    static async Task<string> Step(string name)
    {
        await Task.Delay(1).ConfigureAwait(false);
        return name;
    }

    static async Task Main(string[] args)
    {
        Console.WriteLine(await Step("First"));
        Console.WriteLine(await Step("Second"));
        Console.WriteLine(await Step("Third"));
    }
}

Key points

  • An await normally captures the current synchronization context and resumes on it.
  • ConfigureAwait(false) releases that promise for one await only.
  • A console program has no synchronization context to return to.
  • In a UI program, ConfigureAwait(false) keeps the continuation off the UI thread.
  • The habit belongs in library-style code that callers run under any context.
  • Each await in a method makes its own choice, so the call repeats per await.
  • Print order still follows the awaits, so output stays in program order.

In this example, the Step helper awaits with ConfigureAwait(false) and returns its name. Main awaits three calls one after another. Each result prints as its await completes. The three names print in call order.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

What does ConfigureAwait(false) change about an await?