From kagents
C# concurrency patterns — async/await, Channel<T>, SemaphoreSlim, CancellationToken, Task.WhenAll, parallel execution, producer/consumer, rate limiting. USE FOR: implementing async workflows, choosing concurrency primitives, fixing deadlocks or async anti-patterns. DO NOT USE FOR: general C# syntax (use csharp-patterns) or EF Core query parallelism (use database-performance).
npx claudepluginhub grexyloco/k.agents --plugin kagentsThis skill uses the workspace's default tool permissions.
Adaptiert von: [Aaronontheweb/dotnet-skills](https://github.com/Aaronontheweb/dotnet-skills) (MIT)
Expert guidance for Next.js Cache Components and Partial Prerendering (PPR). **PROACTIVE ACTIVATION**: Use this skill automatically when working in Next.js projects that have `cacheComponents: true` in their next.config.ts/next.config.js. When this config is detected, proactively apply Cache Components patterns and best practices to all React Server Component implementations. **DETECTION**: At the start of a session in a Next.js project, check for `cacheComponents: true` in next.config. If enabled, this skill's patterns should guide all component authoring, data fetching, and caching decisions. **USE CASES**: Implementing 'use cache' directive, configuring cache lifetimes with cacheLife(), tagging cached data with cacheTag(), invalidating caches with updateTag()/revalidateTag(), optimizing static vs dynamic content boundaries, debugging cache issues, and reviewing Cache Component implementations.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Share bugs, ideas, or general feedback.
Adaptiert von: Aaronontheweb/dotnet-skills (MIT)
| Situation | Pattern |
|---|---|
| I/O-bound (HTTP, DB, File) | async/await |
| Parallel CPU-bound | Parallel.ForEachAsync |
| Producer/Consumer | Channel<T> |
| Rate Limiting | SemaphoreSlim |
| Background Work | IHostedService / BackgroundService |
| Fire-and-Forget (mit Fehlerhandling) | Task.Run + Error-Handler |
// ✅ Korrekt
public async Task<User> GetUserAsync(Guid id, CancellationToken ct = default)
{
return await repository.GetByIdAsync(id, ct);
}
// ❌ Verboten: async void (nur für Event-Handler)
// ❌ Verboten: .Result oder .Wait() (Deadlock-Gefahr)
// ❌ Verboten: Task.Run um async zu wrappen
// Immer als letzten Parameter durchreichen
public async Task<List<User>> SearchAsync(string query, CancellationToken ct = default)
{
ct.ThrowIfCancellationRequested();
return await context.Users
.Where(u => u.Name.Contains(query))
.ToListAsync(ct);
}
// ✅ Parallel statt sequentiell
var (users, orders, stats) = await (
userService.GetAllAsync(ct),
orderService.GetRecentAsync(ct),
statsService.GetDashboardAsync(ct)
).WhenAll();
// Extension für Tuple-Destructuring:
public static class TaskExtensions
{
public static async Task<(T1, T2, T3)> WhenAll<T1, T2, T3>(
this (Task<T1>, Task<T2>, Task<T3>) tasks)
{
await Task.WhenAll(tasks.Item1, tasks.Item2, tasks.Item3);
return (tasks.Item1.Result, tasks.Item2.Result, tasks.Item3.Result);
}
}
var channel = Channel.CreateBounded<WorkItem>(100);
// Producer
async Task ProduceAsync(ChannelWriter<WorkItem> writer)
{
await foreach (var item in GetItemsAsync())
{
await writer.WriteAsync(item);
}
writer.Complete();
}
// Consumer
async Task ConsumeAsync(ChannelReader<WorkItem> reader, CancellationToken ct)
{
await foreach (var item in reader.ReadAllAsync(ct))
{
await ProcessAsync(item, ct);
}
}
private static readonly SemaphoreSlim _semaphore = new(maxConcurrency: 10);
public async Task<Result> ProcessWithLimitAsync(CancellationToken ct)
{
await _semaphore.WaitAsync(ct);
try
{
return await DoExpensiveWorkAsync(ct);
}
finally
{
_semaphore.Release();
}
}
ConcurrentDictionary<K,V> statt Dictionary + LockInterlocked.Increment statt lock { counter++ }ImmutableList<T> / FrozenDictionary<K,V> für Read-Heavy Szenarienlock nur für kurze, synchrone Operationenasync Code innerhalb von lock — verwende SemaphoreSlim