Skip to content

ExecutionContext and SynchronizationContext deep dive#52890

Open
BillWagner wants to merge 10 commits intodotnet:mainfrom
BillWagner:async-aweigh-2
Open

ExecutionContext and SynchronizationContext deep dive#52890
BillWagner wants to merge 10 commits intodotnet:mainfrom
BillWagner:async-aweigh-2

Conversation

@BillWagner
Copy link
Copy Markdown
Member

@BillWagner BillWagner commented Apr 7, 2026

Contributes to #17714

  1. Create executioncontext-and-synchronizationcontext.md — from "ExecutionContext vs SynchronizationContext." Covers what each context is, what "flow" means, how async/await interacts with both, why SynchronizationContext.Current doesn't flow across awaits. Most popular post (20 reactions), no existing equivalent.
  2. Create synchronizationcontext-and-console-apps.md — from "Await, SynchronizationContext, and Console Apps" parts 1-3. Needs significant update: add async Task Main(), top-level statements, modern .NET runtime behavior.
  3. Add both to TOC after the wrapper articles.

Summary

Describe your changes here.

Fixes #Issue_Number (if available)


Internal previews

📄 File 🔗 Preview link
docs/navigate/advanced-programming/toc.yml docs/navigate/advanced-programming/toc
docs/standard/asynchronous-programming-patterns/executioncontext-synchronizationcontext.md ExecutionContext and SynchronizationContext
docs/standard/asynchronous-programming-patterns/synchronizationcontext-console-apps.md "SynchronizationContext and console apps"

1. Create `executioncontext-and-synchronizationcontext.md` — from "ExecutionContext vs SynchronizationContext." Covers what each context is, what "flow" means, how async/await interacts with both, why `SynchronizationContext.Current` doesn't flow across awaits. *Most popular post (20 reactions), no existing equivalent.*
1. Create `synchronizationcontext-and-console-apps.md` — from "Await, SynchronizationContext, and Console Apps" parts 1-3. **Needs significant update:** add `async Task Main()`, top-level statements, modern .NET runtime behavior.
1. Add both to TOC after the wrapper articles.
@BillWagner BillWagner marked this pull request as ready for review April 8, 2026 13:39
@BillWagner BillWagner requested a review from a team as a code owner April 8, 2026 13:39
Copilot AI review requested due to automatic review settings April 8, 2026 13:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds two new conceptual articles that explain how ExecutionContext and SynchronizationContext relate to async/await, and how console apps behave (and how to build a single-threaded pump when you need thread affinity).

Changes:

  • Add executioncontext-synchronizationcontext.md with runnable C# and Visual Basic snippets.
  • Add synchronizationcontext-console-apps.md including an AsyncPump-style implementation and snippets.
  • Add both new articles to the advanced programming navigation TOC.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
docs/standard/asynchronous-programming-patterns/executioncontext-synchronizationcontext.md New conceptual article explaining both contexts, flow, and await interactions.
docs/standard/asynchronous-programming-patterns/snippets/executioncontext-synchronizationcontext/csharp/Program.cs C# runnable snippet backing the ExecutionContext/SynchronizationContext article.
docs/standard/asynchronous-programming-patterns/snippets/executioncontext-synchronizationcontext/csharp/ExecutionContextAndSyncContext.csproj C# project for building/running the snippet.
docs/standard/asynchronous-programming-patterns/snippets/executioncontext-synchronizationcontext/vb/Program.vb Visual Basic runnable snippet backing the article.
docs/standard/asynchronous-programming-patterns/snippets/executioncontext-synchronizationcontext/vb/ExecutionContextAndSyncContext.vbproj Visual Basic project for building/running the snippet.
docs/standard/asynchronous-programming-patterns/synchronizationcontext-console-apps.md New article explaining console default behavior and a custom single-threaded context/pump.
docs/standard/asynchronous-programming-patterns/snippets/synchronizationcontext-console-apps/csharp/Program.cs C# runnable snippet implementing the custom context and pump.
docs/standard/asynchronous-programming-patterns/snippets/synchronizationcontext-console-apps/csharp/SyncContextConsoleApps.csproj C# project for building/running the snippet.
docs/standard/asynchronous-programming-patterns/snippets/synchronizationcontext-console-apps/vb/Program.vb Visual Basic runnable snippet implementing the custom context and pump.
docs/standard/asynchronous-programming-patterns/snippets/synchronizationcontext-console-apps/vb/SyncContextConsoleApps.vbproj Visual Basic project for building/running the snippet.
docs/navigate/advanced-programming/toc.yml Adds both new articles to the navigation TOC.

BillWagner and others added 6 commits April 8, 2026 09:49
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Fix feedback, and one final edit pass
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 8 comments.

BillWagner and others added 2 commits April 10, 2026 13:53
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@BillWagner
Copy link
Copy Markdown
Member Author

@adegeo This one is ready for final review.


### The custom context

The context uses a <xref:System.Collections.Concurrent.BlockingCollection%601> to coordinate producers (the async continuations) and a consumer (the pumping loop):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The context uses a <xref:System.Collections.Concurrent.BlockingCollection%601> to coordinate producers (the async continuations) and a consumer (the pumping loop):
The context uses a <xref:System.Collections.Concurrent.BlockingCollection`1> to coordinate producers (the async continuations) and a consumer (the pumping loop):


## Practical considerations

- **Deadlock risk**: If code running inside `AsyncPump.Run` blocks synchronously (for example, by calling `.Result` or `.Wait()` on a task whose continuation must post back to the pump), the pump thread can't process that continuation. The result is a deadlock. The same problem described in [Synchronous wrappers for asynchronous methods](synchronous-wrappers-for-asynchronous-methods.md).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Deadlock risk**: If code running inside `AsyncPump.Run` blocks synchronously (for example, by calling `.Result` or `.Wait()` on a task whose continuation must post back to the pump), the pump thread can't process that continuation. The result is a deadlock. The same problem described in [Synchronous wrappers for asynchronous methods](synchronous-wrappers-for-asynchronous-methods.md).
- **Deadlock risk**: If code running inside `AsyncPump.Run` blocks synchronously (for example, by calling `.Result` or `.Wait()` on a task whose continuation must post back to the pump), the pump thread can't process that continuation. The result is a deadlock. The same problem is described in [Synchronous wrappers for asynchronous methods](synchronous-wrappers-for-asynchronous-methods.md).

---
# ExecutionContext and SynchronizationContext

When you work with `async` and `await`, two context types play important but very different roles: <xref:System.Threading.ExecutionContext> and <xref:System.Threading.SynchronizationContext>. You learn what each one does, how each one interacts with `async`/`await`, and why <xref:System.Threading.SynchronizationContext.Current?displayProperty=nameWithType> doesn't flow across await points.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is use of async/await appropriate for VB devs?

:::code language="csharp" source="./snippets/executioncontext-synchronizationcontext/csharp/Program.cs" id="SyncContextUsage":::
:::code language="vb" source="./snippets/executioncontext-synchronizationcontext/vb/Program.vb" id="SyncContextUsage":::

### Capturing a SynchronizationContext
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Capturing a SynchronizationContext
### Capture a SynchronizationContext


### Task awaiters capture SynchronizationContext

The awaiters for <xref:System.Threading.Tasks.Task> and <xref:System.Threading.Tasks.Task%601> include support for <xref:System.Threading.SynchronizationContext>. The async method builders don't include this support.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The awaiters for <xref:System.Threading.Tasks.Task> and <xref:System.Threading.Tasks.Task%601> include support for <xref:System.Threading.SynchronizationContext>. The async method builders don't include this support.
The awaiters for <xref:System.Threading.Tasks.Task> and <xref:System.Threading.Tasks.Task`1> include support for <xref:System.Threading.SynchronizationContext>. The async method builders don't include this support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants