1. 引言
异步编程是现代C#开发中不可或缺的一部分。本文将深入探讨Task、async/await的工作原理,以及在实际开发中的最佳实践。
2. 异步编程基础
了解Task和async/await的正确使用方式:
// 不推荐的写法 - 同步等待异步操作
public Order GetOrderDetails(int orderId)
{
var orderTask = _orderRepository.GetOrderAsync(orderId);
return orderTask.Result; // 可能导致死锁
}
// 推荐的写法 - 异步一路到底
public async TaskGetOrderDetailsAsync(int orderId)
{
try
{
var order = await _orderRepository.GetOrderAsync(orderId);
if (order == null)
throw new OrderNotFoundException(orderId);
return order;
}
catch (Exception ex)
{
_logger.LogError(ex, "获取订单{OrderId}失败", orderId);
throw;
}
}
3. 高级异步模式
使用高级异步模式处理复杂场景:
public class OrderProcessor
{
private readonly SemaphoreSlim _semaphore = new(3); // 控制并发数
public async TaskProcessOrderAsync(OrderRequest request)
{
// 使用SemaphoreSlim控制并发
await _semaphore.WaitAsync();
try
{
// 并行处理多个任务
var tasks = new List{
ValidateInventoryAsync(request.Items),
CheckUserCreditAsync(request.UserId),
ReserveCapacityAsync(request.DeliveryDate)
};
await Task.WhenAll(tasks);
// 使用CancellationToken支持取消操作
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
return await FinalizeOrderAsync(request, cts.Token);
}
finally
{
_semaphore.Release();
}
}
private async TaskFinalizeOrderAsync(
OrderRequest request,
CancellationToken cancellationToken)
{
using var scope = _logger.BeginScope(
new Dictionary{
["OrderId"] = request.OrderId,
["UserId"] = request.UserId
});
// 实现重试机制
var policy = Policy
.Handle()
.WaitAndRetryAsync(3, retryAttempt =>
TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
return await policy.ExecuteAsync(async () =>
{
// 处理订单逻辑
return await _orderService.FinalizeAsync(request, cancellationToken);
});
}
}
4. 异步最佳实践
// 实现高效的异步缓存
public class AsyncCache{
private readonly ConcurrentDictionary_locks = new();
private readonly ConcurrentDictionary_cache = new();
private readonly Func> _valueFactory;
public async TaskGetOrAddAsync(TKey key)
{
if (_cache.TryGetValue(key, out var value))
return value;
var semaphore = _locks.GetOrAdd(key, _ => new SemaphoreSlim(1, 1));
await semaphore.WaitAsync();
try
{
if (_cache.TryGetValue(key, out value))
return value;
value = await _valueFactory(key);
_cache[key] = value;
return value;
}
finally
{
semaphore.Release();
}
}
}
5. 性能优化建议
使用ValueTask减少内存分配
合理使用异步并行处理
实现高效的异步缓存机制
正确处理任务取消
6. 总结
掌握C#异步编程不仅能提升应用性能,还能帮助我们构建更可靠的系统。通过合理使用Task、async/await和各种异步模式,我们可以开发出高效且可维护的应用程序。