Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 8.2 Task与async/await

8.2 Task与async/await

概述

在现代C#开发中,异步编程已成为提高应用程序响应能力和资源利用率的关键技术。Task和async/await是.NET框架中实现异步编程的核心机制,它们使得编写异步代码变得简单直观,同时保持了代码的可读性和可维护性。

Task类基础

什么是Task

  • Task类表示一个异步操作,位于System.Threading.Tasks命名空间
  • 可以表示已完成、正在运行或将要运行的异步操作
  • 提供了检查任务状态、等待完成和获取结果的方法

创建和启动Task

// 使用Task.Run创建并启动后台任务
Task.Run(() => {
    // 长时间运行的操作
    Console.WriteLine("任务正在运行...");
});

// 使用Task.Factory.StartNew
Task.Factory.StartNew(() => {
    // 工作代码
});

任务状态与生命周期

  • Created:任务已初始化但尚未计划
  • WaitingForActivation:任务等待激活
  • Running:任务正在执行
  • RanToCompletion:任务成功完成
  • Faulted:任务因未处理异常而完成
  • Canceled:任务因取消而完成

async/await模式

基本语法

public async Task<string> GetDataAsync()
{
    // 模拟异步操作
    await Task.Delay(1000);
    return "数据已加载";
}

关键概念

  1. async修饰符:标记方法为异步方法
  2. await运算符:暂停方法执行,直到等待的任务完成
  3. 返回类型:通常为Task、Task<T>或ValueTask<T>

执行流程

  1. 调用异步方法时,同步执行直到第一个await
  2. 遇到await时,方法返回一个Task,控制权交回调用者
  3. 当await的任务完成后,方法从await处恢复执行

异常处理

捕获异步异常

try
{
    await SomeAsyncOperation();
}
catch (Exception ex)
{
    Console.WriteLine($"发生错误: {ex.Message}");
}

多个任务的异常处理

try
{
    Task task1 = Task1Async();
    Task task2 = Task2Async();
    await Task.WhenAll(task1, task2);
}
catch (AggregateException ae)
{
    foreach (var ex in ae.InnerExceptions)
    {
        Console.WriteLine(ex.Message);
    }
}

任务组合

Task.WhenAll

等待所有提供的任务完成

Task<int> task1 = GetValue1Async();
Task<int> task2 = GetValue2Async();

int[] results = await Task.WhenAll(task1, task2);

Task.WhenAny

等待任何一个提供的任务完成

Task<string> task1 = DownloadFromSource1Async();
Task<string> task2 = DownloadFromSource2Async();

Task<string> firstFinished = await Task.WhenAny(task1, task2);
string result = await firstFinished;

性能考虑

避免async void

  • 只应在事件处理程序中使用async void
  • 其他情况应使用async Task,以便调用者可以await和捕获异常

ConfigureAwait

await SomeAsyncOperation().ConfigureAwait(false);
  • 当不需要返回到原始上下文时使用,可提高性能
  • 特别适用于库代码

ValueTask

对于可能同步完成的操作,考虑使用ValueTask<T>

public ValueTask<int> GetCachedValueAsync()
{
    if (cache.TryGetValue(key, out var value))
        return new ValueTask<int>(value);
    
    return new ValueTask<int>(LoadValueAsync());
}

实际应用示例

异步HTTP请求

public async Task<string> GetWebContentAsync(string url)
{
    using (HttpClient client = new HttpClient())
    {
        return await client.GetStringAsync(url);
    }
}

并行处理

public async Task ProcessMultipleItemsAsync(IEnumerable<Item> items)
{
    var tasks = items.Select(item => ProcessItemAsync(item));
    await Task.WhenAll(tasks);
}

常见陷阱与最佳实践

  1. 避免死锁:不要在UI线程上使用.Result或.Wait()
  2. 合理使用异步:不是所有方法都需要异步,仅对I/O密集型或长时间运行的操作使用
  3. 命名约定:异步方法应以"Async"后缀命名
  4. 取消支持:考虑支持CancellationToken
  5. 避免过度并行:控制并发任务数量

总结

Task和async/await为C#开发者提供了强大而优雅的异步编程模型。通过合理使用这些特性,可以编写出高效、响应迅速的应用程序,同时保持代码的清晰和可维护性。掌握这些概念是现代C#开发者的必备技能。

Last Updated:: 5/3/25, 11:34 PM