Modern C# asynchronous programming patterns using async/await, proper CancellationToken usage, and error handling in async code. Use when guidance needed on async/await best practices, Task composition and coordination, ConfigureAwait usage, ValueTask optimization, or async operation cancellation patterns. Pure .NET framework patterns applicable to any C# application.
C# 비동기 프로그래밍 패턴 (POCU 표준 적용)
Foundation Required: csharp-code-style (mPascalCase, Async 접미사 금지, var 금지)
Core Topics:
public class DataService
{
private readonly IDataRepository mRepository;
private readonly ILogger mLogger;
public DataService(IDataRepository repository, ILogger logger)
{
mRepository = repository;
mLogger = logger;
}
// ✅ POCU: Async 접미사 없음
public async Task<Data> LoadData(CancellationToken ct = default)
{
try
{
Data data = await mRepository.Fetch(ct);
return processData(data);
}
catch (OperationCanceledException)
{
mLogger.Info("Operation cancelled");
throw;
}
}
private Data processData(Data data)
{
Debug.Assert(data != null);
// Processing logic
return data;
}
}
// ❌ WRONG: Async 접미사 사용
public async Task<Order> GetOrderAsync(int id);
public async Task SaveOrderAsync(Order order);
// ✅ CORRECT: Async 접미사 없음
public async Task<Order> GetOrder(int id);
public async Task SaveOrder(Order order);
// ❌ WRONG: async void
public async void LoadData()
{
await mRepository.Fetch();
}
// ✅ CORRECT: async Task
public async Task LoadData()
{
await mRepository.Fetch();
}
// ⚠️ EXCEPTION: 이벤트 핸들러만 async void 허용
private async void OnButtonClick(object sender, EventArgs e)
{
try
{
await ProcessClick();
}
catch (Exception ex)
{
mLogger.Error(ex, "Click handler failed");
}
}
// ❌ WRONG: var 사용
var result = await GetOrder(1);
var tasks = new List<Task>();
// ✅ CORRECT: 명시적 타입
Order result = await GetOrder(1);
List<Task> tasks = new List<Task>();
// ❌ WRONG: using 선언
using CancellationTokenSource cts = new CancellationTokenSource(timeout);
// ✅ CORRECT: using 문
using (CancellationTokenSource cts = new CancellationTokenSource(timeout))
{
return await LoadData(cts.Token);
}
public class OrderProcessor
{
private readonly IOrderRepository mRepository;
// 항상 CancellationToken 지원
public async Task<Order> ProcessOrder(int orderId, CancellationToken ct = default)
{
ct.ThrowIfCancellationRequested();
Order order = await mRepository.GetOrder(orderId, ct);
Debug.Assert(order != null);
await validateOrder(order, ct);
await calculateTotal(order, ct);
await mRepository.SaveOrder(order, ct);
return order;
}
private async Task validateOrder(Order order, CancellationToken ct)
{
Debug.Assert(order != null);
await mRepository.ValidateInventory(order.Items, ct);
}
private async Task calculateTotal(Order order, CancellationToken ct)
{
Debug.Assert(order != null);
decimal total = 0;
foreach (OrderItem item in order.Items)
{
ct.ThrowIfCancellationRequested();
total += item.Price * item.Quantity;
}
order.Total = total;
}
}
Essential patterns for async/await:
Comprehensive code examples:
Common mistakes to avoid:
npx skills add creator-hian/csharp-async-patterns下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer