Agent skill

Csharp Concurrency Patterns

by Aaronontheweb in Aaronontheweb/dotnet-skills

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.

MITAuto-check passedDevelopment

Install Csharp Concurrency Patterns

skills CLI
$ npx skills add Aaronontheweb/dotnet-skills --skill csharp-concurrency-patterns -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install Aaronontheweb/dotnet-skills csharp-concurrency-patterns --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/Aaronontheweb/dotnet-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/csharp-concurrency-patterns .claude/skills/csharp-concurrency-patterns && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
csharp-concurrency-patterns
GitHub stars
1.2k
Used in
1 other repo
Token cost
~2.2k tokens
SKILL.md length
483 words
Files
2
Skills in repo
33
Repo updated
First seen
Licence
MIT

At a glance

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.

  • Works in 4 steps: First choice: Redesign to avoid it… → Second choice: Use… → Third choice: Use Channel to serialize… → …
  • Tasks that involve Async programming
  • SKILL.md covers When to Use This Skill, Reference Files, The Philosophy and Decision Tree, plus 7 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Csharp Concurrency Patterns is an agent skill from Aaronontheweb/dotnet-skills. 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. Avoid locks and manual synchronization unless absolutely necessary.

Its SKILL.md is about 2.2k tokens, which your agent loads only when the skill is triggered. The skill folder holds 1 other file (for example `advanced-concurrency.md`).

It sits in Development, covering Async programming. It works with .NET and C#. The repository describes itself as: Claude Code skills and sub-agents for .NET Developers. The licence is MIT.

When your agent uses it

  • Tasks that involve Async programming

Example prompts

  • “/csharp-concurrency-patterns”

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. First choice: Redesign to avoid it (immutability, message passing, actor isolation)
  2. Second choice: Use System.Collections.Concurrent (ConcurrentDictionary, etc.)
  3. Third choice: Use Channel to serialize access through message passing
  4. Last resort: Use lock for simple, short-lived critical sections

What it can do on your machine

Read from SKILL.md and the folder at commit e426ed9. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are csharp).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Csharp Concurrency Patterns loads about 2.2k tokens when it runs. Until then it costs about 63 tokens; SKILL.md has 483 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~63
When it runs · the whole SKILL.md, loaded when a task matches
~2.2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from Aaronontheweb/dotnet-skills at commit e426ed9, republished under its MIT licence (© Aaronontheweb). 483 words, ~2,189 tokens.

Download SKILL.mdSave it as .claude/skills/csharp-concurrency-patterns/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
csharp-concurrency-patterns
description
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. Avoid locks and manual synchronization unless absolutely necessary.
invocable
false

.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

Reference Files

  • advanced-concurrency.md: Akka.NET Streams, Reactive Extensions, Akka.NET Actors (entity-per-actor, state machines, cluster sharding), and async local function patterns

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:

  1. First choice: Redesign to avoid it (immutability, message passing, actor isolation)
  2. Second choice: Use System.Collections.Concurrent (ConcurrentDictionary, etc.)
  3. Third choice: Use Channel<T> to serialize access through message passing
  4. Last resort: Use lock for simple, short-lived critical sections

Decision Tree

What are you trying to do?
│
├─► Wait for I/O (HTTP, database, file)?
│   └─► Use async/await
│
├─► Process a collection in parallel (CPU-bound)?
│   └─► Use Parallel.ForEachAsync
│
├─► Producer/consumer pattern (work queue)?
│   └─► Use System.Threading.Channels
│
├─► UI event handling (debounce, throttle, combine)?
│   └─► Use Reactive Extensions (Rx)
│
├─► Server-side stream processing (backpressure, batching)?
│   └─► Use Akka.NET Streams
│
├─► State machines with complex transitions?
│   └─► Use Akka.NET Actors (Become pattern)
│
├─► Manage state for many independent entities?
│   └─► Use Akka.NET Actors (entity-per-actor)
│
├─► Coordinate multiple async operations?
│   └─► Use Task.WhenAll / Task.WhenAny
│
└─► None of the above fits?
    └─► Ask yourself: "Do I really need shared mutable state?"
        ├─► Yes → Consider redesigning to avoid it
        └─► Truly unavoidable → Use Channels or Actors to serialize access

Level 1: async/await (Default Choice)

Use for: I/O-bound operations, non-blocking waits, most everyday concurrency.

csharp
// Simple async I/O
public async Task<Order> GetOrderAsync(string orderId, CancellationToken ct)
{
    var order = await _database.GetAsync(orderId, ct);
    var customer = await _customerService.GetAsync(order.CustomerId, ct);
    return order with { Customer = customer };
}

// Parallel async operations (when independent)
public async Task<Dashboard> LoadDashboardAsync(string userId, CancellationToken ct)
{
    var ordersTask = _orderService.GetRecentOrdersAsync(userId, ct);
    var notificationsTask = _notificationService.GetUnreadAsync(userId, ct);
    var statsTask = _statsService.GetUserStatsAsync(userId, ct);

    await Task.WhenAll(ordersTask, notificationsTask, statsTask);

    return new Dashboard(
        Orders: await ordersTask,
        Notifications: await notificationsTask,
        Stats: await statsTask);
}

Key principles: Always accept CancellationToken. Use ConfigureAwait(false) in library code. Don't block on async code.


Level 2: Parallel.ForEachAsync (CPU-Bound Parallelism)

Use for: Processing collections in parallel when work is CPU-bound or you need controlled concurrency.

csharp
public async Task ProcessOrdersAsync(
    IEnumerable<Order> orders,
    CancellationToken ct)
{
    await Parallel.ForEachAsync(
        orders,
        new ParallelOptions
        {
            MaxDegreeOfParallelism = Environment.ProcessorCount,
            CancellationToken = ct
        },
        async (order, token) =>
        {
            await ProcessOrderAsync(order, token);
        });
}

When NOT to use: Pure I/O operations, when order matters, when you need backpressure.


Level 3: System.Threading.Channels (Producer/Consumer)

Use for: Work queues, producer/consumer patterns, decoupling producers from consumers.

csharp
public class OrderProcessor
{
    private readonly Channel<Order> _channel;

    public OrderProcessor()
    {
        _channel = Channel.CreateBounded<Order>(new BoundedChannelOptions(100)
        {
            FullMode = BoundedChannelFullMode.Wait
        });
    }

    // Producer
    public async Task EnqueueOrderAsync(Order order, CancellationToken ct)
    {
        await _channel.Writer.WriteAsync(order, ct);
    }

    // Consumer (run as background task)
    public async Task ProcessOrdersAsync(CancellationToken ct)
    {
        await foreach (var order in _channel.Reader.ReadAllAsync(ct))
        {
            await ProcessOrderAsync(order, ct);
        }
    }

    public void Complete() => _channel.Writer.Complete();
}

Channels are good for: Decoupling speed, buffering with backpressure, fan-out to workers, background queues.

Channels are NOT good for: Complex stream operations (batching, windowing), stateful per-entity processing, sophisticated supervision.


Show full SKILL.md (178 more words)Show less

Level 4+: Akka.NET Streams, Reactive Extensions, Actors

For advanced scenarios requiring stream processing, UI event composition, or stateful entity management, see advanced-concurrency.md.

Akka.NET Streams excel at server-side batching, throttling, and backpressure. Reactive Extensions are ideal for UI event composition. Akka.NET Actors handle entity-per-actor patterns, state machines with Become(), and distributed systems via Cluster Sharding.


Anti-Patterns: What to Avoid

Locks for Business Logic
csharp
// BAD: Using locks to protect shared state
private readonly object _lock = new();
private Dictionary<string, Order> _orders = new();

public void UpdateOrder(string id, Action<Order> update)
{
    lock (_lock) { if (_orders.TryGetValue(id, out var order)) update(order); }
}

// GOOD: Use an actor or Channel to serialize access
Manual Thread Management
csharp
// BAD: Creating threads manually
var thread = new Thread(() => ProcessOrders());
thread.Start();

// GOOD: Use Task.Run or better abstractions
_ = Task.Run(() => ProcessOrdersAsync(cancellationToken));
Blocking in Async Code
csharp
// BAD: Blocking on async - deadlock risk!
var result = GetDataAsync().Result;

// GOOD: Async all the way
var result = await GetDataAsync();
Shared Mutable State Without Protection
csharp
// BAD: Multiple tasks mutating shared state
var results = new List<Result>();
await Parallel.ForEachAsync(items, async (item, ct) =>
{
    var result = await ProcessAsync(item, ct);
    results.Add(result); // Race condition!
});

// GOOD: Use ConcurrentBag
var results = new ConcurrentBag<Result>();

Quick Reference: Which Tool When?

NeedToolExample
Wait for I/Oasync/awaitHTTP calls, database queries
Parallel CPU workParallel.ForEachAsyncImage processing, calculations
Work queueChannel<T>Background job processing
UI events with debounce/throttleReactive ExtensionsSearch-as-you-type, auto-save
Server-side batching/throttlingAkka.NET StreamsEvent aggregation, rate limiting
State machinesAkka.NET ActorsPayment flows, order lifecycles
Entity state managementAkka.NET ActorsOrder management, user sessions
Fire multiple async opsTask.WhenAllLoading dashboard data
Race multiple async opsTask.WhenAnyTimeout with fallback
Periodic workPeriodicTimerHealth checks, polling

The Escalation Path

async/await (start here)
    │
    ├─► Need parallelism? → Parallel.ForEachAsync
    │
    ├─► Need producer/consumer? → Channel<T>
    │
    ├─► Need UI event composition? → Reactive Extensions
    │
    ├─► Need server-side stream processing? → Akka.NET Streams
    │
    └─► Need state machines or entity management? → Akka.NET Actors

Only escalate when you have a concrete need. Don't reach for actors or streams "just in case".

© Aaronontheweb, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file in skills/csharp-concurrency-patterns of Aaronontheweb/dotnet-skills.

  • SKILL.md
  • advanced-concurrency.md

Open the folder on GitHubat commit e426ed9

Used in 1 other repository

We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in Aaronontheweb/dotnet-skills, which our catalogue first saw on October 7, 2026.

Compare with similar skills

Csharp Concurrency Patterns next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Csharp Concurrency Patterns compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Csharp Concurrency Patterns this skillAaronontheweb/dotnet-skills1.2k1 repos~2.2kAutomated safety check: PassMIT
Dotnet Csharpnovotnyllc/dotnet-artisan233—~1.7kAutomated safety check: PassMIT
Csharp Prodavila7/claude-code-templates32k7 repos~538Automated safety check: PassMIT
Dotnet Patternsaffaan-m/ECC274k1 repos~2.3kAutomated safety check: PassMIT
Dotnet Patternsaffaan-m/ECC274k—~2.1kAutomated safety check: PassMIT
Csharp Patternssoftspark/ai-toolkit179—~3.6kAutomated safety check: PassApache-2.0

Similar skills

  • Dotnet Csharp

    novotnyllc/dotnet-artisan

    Baseline C skill loaded for every .NET code path. An agent skill from novotnyllc/dotnet-artisan.

    233 GitHub stars~1.7k tokensUpdated 1 mo ago
    DevelopmentAuto-check passed
  • Csharp Pro

    davila7/claude-code-templates

    Write modern C code with advanced features like records, pattern matching, and async/await.

    32k GitHub starsUsed in 7 repos~538 tokens
    DevelopmentAuto-check passed
  • Dotnet Patterns

    affaan-m/ECC

    Idiomatic C and .NET patterns, conventions, dependency injection, async/await, and best practices for building robust, maintainable .NET applications.

    274k GitHub starsUsed in 1 repo~2.3k tokens
    DevelopmentAuto-check passed
  • Dotnet Patterns

    affaan-m/ECC

    惯用的C和.NET模式、约定、依赖注入、async/await以及构建健壮、可维护的.NET应用程序的最佳实践. An agent skill from affaan-m/ECC.

    274k GitHub stars~2.1k tokensUpdated 2 days ago
    DevelopmentAuto-check passed
  • Csharp Patterns

    softspark/ai-toolkit

    C/.NET: LINQ, async/await, DI, records, nullable refs, ASP.NET Core, EF Core, MediatR.

    179 GitHub stars~3.6k tokensUpdated today
    DevelopmentAuto-check passed
  • Csharp Idioms

    irahardianto/awesome-agv

    Modern C (10+/.NET) coding idioms: nullable reference types, records, pattern matching, async/await with CancellationTokens, LINQ performance, and DI.

    157 GitHub stars~1.3k tokensUpdated 2 days ago
    DevelopmentAuto-check passed

More from Aaronontheweb/dotnet-skills

All 33 skills in this repo
  • .NET API Compatibility Design

    Aaronontheweb/dotnet-skills

    Applies extend-only design rules to NuGet packages and distributed systems, covering source, binary and wire compatibility and how to deprecate members safely.

    1.2k GitHub starsUsed in 2 repos~2.7k tokens
    Auto-check passed
  • .NET Trimming and Native AOT

    Aaronontheweb/dotnet-skills

    Guides making .NET libraries trimming-safe and Native-AOT compatible: the MSBuild properties, trimming attributes, warning codes and a playbook of safe patterns.

    1.2k GitHub stars~2.9k tokensUpdated 19 days ago
    Auto-check passed
  • Akka.Hosting Actor Patterns

    Aaronontheweb/dotnet-skills

    Shows how to build entity actors with Akka.Hosting so the same code runs in local unit tests and in a sharded cluster in production.

    1.2k GitHub starsUsed in 1 repo~5k tokens
    Auto-check passed
  • Akka.NET Best Practices

    Aaronontheweb/dotnet-skills

    Guidance for Akka.NET actor systems covering EventStream versus DistributedPubSub, supervision, Props versus DependencyResolver, work distribution and testable cluster code.

    1.2k GitHub starsUsed in 1 repo~3.3k tokens
    Auto-check passed
  • Akka.NET Management and Discovery

    Aaronontheweb/dotnet-skills

    Sets up Akka.Management and Cluster.Bootstrap so Akka.NET clusters form through service discovery on Kubernetes, Azure or config instead of static seed nodes.

    1.2k GitHub starsUsed in 1 repo~2.5k tokens
    Auto-check passed
  • Akka.NET Testing Patterns

    Aaronontheweb/dotnet-skills

    Shows how to test Akka.NET actors with Akka.Hosting.TestKit: swapping services for fakes, using TestProbes, and checking persistence, plus when the older TestKit still fits.

    1.2k GitHub starsUsed in 1 repo~2.4k tokens
    Auto-check passed

Works with

Categories

Questions about Csharp Concurrency Patterns

What does Csharp Concurrency Patterns do?

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. Csharp Concurrency Patterns is an agent skill from Aaronontheweb/dotnet-skills.NET for stateful entity management.

When should I use Csharp Concurrency Patterns?

Csharp Concurrency Patterns fits situations like: tasks that involve Async programming.

How do I install Csharp Concurrency Patterns in Claude Code?

Run `npx skills add Aaronontheweb/dotnet-skills --skill csharp-concurrency-patterns -a claude-code`. Or copy the skill folder (skills/csharp-concurrency-patterns in Aaronontheweb/dotnet-skills) into .claude/skills/csharp-concurrency-patterns in your project. Claude Code loads it when a task matches its description.

How do I install Csharp Concurrency Patterns in Codex?

Run `npx skills add Aaronontheweb/dotnet-skills --skill csharp-concurrency-patterns -a codex`. Or copy the skill folder (skills/csharp-concurrency-patterns in Aaronontheweb/dotnet-skills) into .agents/skills/csharp-concurrency-patterns in your project. Codex loads it when a task matches its description.

Can I use Csharp Concurrency Patterns in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Aaronontheweb/dotnet-skills --skill csharp-concurrency-patterns -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/csharp-concurrency-patterns, .gemini/skills/csharp-concurrency-patterns, .github/skills/csharp-concurrency-patterns and .opencode/skills/csharp-concurrency-patterns in your project.

What does Csharp Concurrency Patterns need to run?

SKILL.md names no scripts, command-line tools or credentials: Csharp Concurrency Patterns is instructions for the agent only.

Does Csharp Concurrency Patterns access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Csharp Concurrency Patterns safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Csharp Concurrency Patterns use?

Csharp Concurrency Patterns is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Csharp Concurrency Patterns use?

About 2.2k tokens (SKILL.md is roughly 8.8k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Csharp Concurrency Patterns?

Skills that share tags, products or a category with Csharp Concurrency Patterns: Dotnet Csharp (novotnyllc/dotnet-artisan, 233 stars), Csharp Pro (davila7/claude-code-templates, 32k stars), Dotnet Patterns (affaan-m/ECC, 274k stars) and Dotnet Patterns (affaan-m/ECC, 274k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Csharp Concurrency Patterns?

Aaronontheweb (a GitHub user) maintains it in Aaronontheweb/dotnet-skills, which has 1,202 GitHub stars. The repository holds 33 skills in this directory. The repository was last updated on September 17, 2026.

Source: Aaronontheweb/dotnet-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.