wshaddix/dotnet-skills/csharp-concurrency-patterns
Claude Code and agent skill by wshaddix/dotnet-skills
- community
Checking that the SKILL.md file is still in the repository.
Choosing the right concurrency abstraction in .NET - from async/await for I/O to Channels for producer/consumer to Akka.NET for stateful entity management. Covers both high-level abstractions and low-level synchronization primitives. Use when deciding how to handle concurrent operations in .NET, evaluating whether to use async/await, Channels, or Akka.NET, or managing state across multiple concurrent entities.
Install
npx vskill@latest install wshaddix/dotnet-skills/csharp-concurrency-patternsSKILL.md
.NET Concurrency: Choosing the Right Tool
When to Use This Skill
Use this skill when:
- Deciding how to handle concurrent operations in .NET
- Evaluating whether to use async/await, Channels, Akka.NET, or other abstractions
- Tempted to use locks, semaphores, or other synchronization primitives
- Need to process streams of data with backpressure, batching, or debouncing
- Managing state across multiple concurrent entities
The Philosophy
Start simple, escalate only when needed.
Most concurrency problems can be solved with async/await. Only reach for more sophisticated tools when you have a specific need that async/await can't address cleanly.
Try to avoid shared mutable state. The best way to handle concurrency is to design it away. Immutable data, message passing, and isolated state (like actors) eliminate entire categories of bugs.
Locks should be the exception, not the rule. When you can't avoid shared mutable state, using a lock occasionally isn't the end of the world. But if you find yourself reaching for lock, SemaphoreSlim, or other synchronization primitives regularly, step back and reconsider your design.
When you truly need shared mutable state:
- First choice: Redesign to avoid it (immutability, message passing, actor isolation)
- Second choice: Use
System.Collections.Concurrent(ConcurrentDictionary, ConcurrentQueue, etc.) - Third choice: Use
Channel<T>to serialize access through message passing - Last resort: Use
lockfor simple, short-lived critical sections
Decision Tree
Level 1: async/await (Default Choice)
Use for: I/O-bound operations, non-blocking waits, most everyday concurrency.
Key principles:
- Always accept
CancellationToken - Use
ConfigureAwait(false)in library code - Don't block on async code (no
.Resultor.Wait())
Level 2: Parallel.ForEachAsync (CPU-Bound Parallelism)
Use for: Processing collections in parallel when work is CPU-bound or you need controlled concurrency.
When NOT to use:
- Pure I/O operations (async/await is sufficient)
- When order matters (Parallel doesn't preserve order)
- When you need backpressure or flow control
Level 3: System.Threading.Channels (Producer/Consumer)
Use for: Work queues, producer/consumer patterns, decoupling producers from consumers, simple stream-like processing.
Channels are good for:
- Decoupling producer speed from consumer speed
- Buffering work with backpressure
- Simple fan-out to multiple workers
- Background processing queues
Channels are NOT good for:
- Complex stream operations (batching, windowing, merging)
- Stateful processing per entity
- When you need sophisticated error handling/supervision
Level 4: Akka.NET Streams (Complex Stream Processing)
Use for: Backpressure, batching, debouncing, throttling, merging streams, complex transformations.
Level 4b: Reactive Extensions (UI and Event Composition)
Use for: UI event handling, composing event streams, time-based operations in client applications.
Rx vs Akka.NET Streams:
| Scenario | Rx | Akka.NET Streams | |
|---|---|---|---|
| UI events | Best choice | Overkill | |
| Client-side composition | Best choice | Overkill | |
| Server-side pipelines | Works but limited | Better backpressure | |
| Distributed processing | Not designed for | Built for this | |
| Hot observables | Native support | Requires more setup |
Level 5: Akka.NET Actors (Stateful Concurrency)
Use for: Managing state for multiple entities, state machines, push-based updates, complex coordination, supervision and fault tolerance.
Entity-Per-Actor Pattern
State Machines with Become
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/csharp-concurrency-patterns/SKILL.md
Popularity
- Repository stars
- 1
- 7-day trend score
- 3
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 18 Mar 2026, 7 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/wshaddix/dotnet-skills/csharp-concurrency-patterns)