答案是基于async和await的TAP模式是C#推荐的异步编程方式,它通过非阻塞I/O提升响应性和吞吐量,适用于I/O密集型操作,结合Task.Run可处理CPU密集型任务,相比传统多线程更简洁高效,避免回调地狱,需注意async void、ConfigureAwait和异常处理等最佳实践。

C#的异步编程模式,说到底,我们现在最常用也最推荐的,就是基于
async
await
实现C#的异步编程,核心就是围绕着
async
await
Task
Task<TResult>
首先,你需要将一个方法标记为
async
await
async
await
public async Task<string> FetchDataAsync()
{
// ...
}接着,在
async
Task
Task<TResult>
await
await
await
await
举个例子,假设我们想从一个API获取数据:
using System;
using System.Net.Http;
using System.Threading.Tasks;
public class DataService
{
private readonly HttpClient _httpClient = new HttpClient();
public async Task<string> GetExternalDataAsync(string url)
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 开始请求数据...");
// 当执行到这里时,方法会暂停,并释放当前线程。
// 网络请求在后台进行,线程可以去做其他事情。
string data = await _httpClient.GetStringAsync(url);
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 数据请求完成。");
return data;
}
public async Task ProcessDataAsync()
{
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 开始处理流程...");
string result = await GetExternalDataAsync("https://jsonplaceholder.typicode.com/todos/1");
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 接收到的数据长度: {result.Length}");
// 这里可以继续处理result
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 流程处理完毕。");
}
// 主调用方,通常是一个UI事件处理程序或控制台应用的Main方法
public static async Task Main(string[] args)
{
DataService service = new DataService();
// 调用异步方法
await service.ProcessDataAsync();
Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 主程序继续执行其他操作...");
// 确保异步操作有足够时间完成,对于控制台应用,通常需要保持主线程活跃
// Console.ReadLine(); // 如果没有其他异步操作,可以用这个保持程序运行
}
}在这个例子里,当
GetExternalDataAsync
_httpClient.GetStringAsync(url)
await
GetStringAsync
对于CPU密集型操作,如果你想让它不阻塞调用线程,可以结合
Task.Run
public async Task<long> CalculateFactorialAsync(int n)
{
// 将CPU密集型计算放到线程池线程中执行,避免阻塞UI线程或请求处理线程。
long result = await Task.Run(() =>
{
long factorial = 1;
for (int i = 1; i <= n; i++)
{
factorial *= i;
}
return factorial;
});
return result;
}这样,
Task.Run
await
CalculateFactorialAsync
async/await
在我看来,
async/await
async/await
async/await
async/await
虽然
async/await
一个常见的误区是使用
async void
async void
Task
async Task
async Task<TResult>
async void
await
async void
// 避免:难以追踪完成和异常
public async void BadAsyncVoidMethod()
{
await Task.Delay(1000);
throw new InvalidOperationException("Oops!"); // 这个异常很难被捕获
}
// 推荐:返回Task,可以被await,异常可捕获
public async Task GoodAsyncTaskMethod()
{
await Task.Delay(1000);
// throw new InvalidOperationException("Oops!");
}另一个需要注意的点是
ConfigureAwait(false)
await
Task
await
await
.Result
.Wait()
所以,在库代码或不需要特定上下文的后端服务中,我通常会建议在
await
.ConfigureAwait(false)
// 库方法或后端服务中,通常不需要回到原始上下文
public async Task<string> FetchAndProcessDataAsync(string url)
{
// 不回到原始上下文,提高性能,避免死锁
string data = await _httpClient.GetStringAsync(url).ConfigureAwait(false);
// 这里可以继续处理data
return data.ToUpperInvariant();
}这样告诉运行时,异步操作完成后,不需要强制回到原始上下文,可以在任何可用的线程池线程上继续执行,这有助于减少开销并避免潜在的死锁问题。但请记住,一旦你使用了
ConfigureAwait(false)
await
最后,异常处理。异步方法中的异常处理和同步方法类似,可以使用
try-catch
Task
await
await
Task
await
Task
.Result
.Wait()
Task
await
public async Task RobustOperationAsync()
{
try
{
string data = await _httpClient.GetStringAsync("http://invalid.url").ConfigureAwait(false);
Console.WriteLine(data);
}
catch (HttpRequestException ex)
{
Console.WriteLine($"网络请求失败: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"发生未知错误: {ex.Message}");
}
}async/await
这是一个经常被问到的问题,也常常被混淆。在我看来,理解
async/await
Thread
ThreadPool
Parallel.For
最核心的区别在于:
async/await
await
Task
await
Task
await
async/await
而传统的多线程编程,比如直接创建
new Thread()
ThreadPool.QueueUserWorkItem
Task.Run
await
Parallel.For
ForEach
简单来说:
async/await
当然,两者并非完全独立。在某些情况下,你会希望将一个CPU密集型任务转换为异步操作,以便不阻塞调用线程。这时,你就可以结合使用
Task.Run
await
// CPU密集型任务,但希望通过async/await使其不阻塞调用线程
public async Task<int> PerformCpuIntensiveWorkAsync()
{
// Task.Run 将计算任务调度到线程池,await 等待结果
int result = await Task.Run(() =>
{
// 模拟一个耗时的CPU计算
int sum = 0;
for (int i = 0; i < 1_000_000_000; i++)
{
sum += i;
}
return sum;
});
return result;
}这里,
Task.Run
await
PerformCpuIntensiveWorkAsync
以上就是C#的异步编程模式是什么?如何实现?的详细内容,更多请关注php中文网其它相关文章!
编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号