C# 异步方法

先用几个例子展示这个语法糖的优势

复制代码
public async Task<bool> ComplexBusinessFlow_Clean(int orderId)
{
    try
    {
        // 1. 验证订单
        var validation = await orderService.ValidateOrderAsync(orderId);
        if (!validation.IsValid)
            return false;
        
        // 2. 处理支付
        var paymentResult = await paymentService.ProcessPaymentAsync(orderId);
        if (!paymentResult.Success)
            return false;
        
        // 3. 更新库存
        await inventoryService.UpdateStockAsync(orderId);
        
        // 4. 发送确认邮件
        await emailService.SendConfirmationAsync(orderId);
        
        Console.WriteLine("业务流程完成");
        return true;
    }
    catch (Exception ex)
    {
        logger.LogError(ex, $"订单 {orderId} 处理失败");
        return false;
    }
}
执行顺序分析

// 1. 验证订单 - 第一步 var validation = await

orderService.ValidateOrderAsync(orderId);

// 2. 处理支付 - 第二步(必须等第一步完成) var paymentResult = await paymentService.ProcessPaymentAsync(orderId);

// 3. 更新库存 - 第三步(必须等第二步完成) await inventoryService.UpdateStockAsync(orderId);

// 4. 发送确认邮件 - 第四步(必须等第三步完成) await emailService.SendConfirmationAsync(orderId);

关键特性 //用写同步代码的风格达到了异步执行的效果
  1. 顺序执行 :每个 await都会等待前一个异步操作完成后再执行下一个

  2. 非阻塞:虽然顺序执行,但不会阻塞线程(在等待时可以处理其他任务)

  3. 异常处理统一的 try-catch块确保任何步骤出错都会进入异常处理

    private async void btnLoadData_Click(object sender, EventArgs e)
    {
    try
    {
    progressBar.Visible = true;
    btnLoad.Enabled = false;

    复制代码
         // ✅ 异步等待,不阻塞UI线程
         var data = await httpClient.GetStringAsync(url);
         
         // 自动回到UI线程上下文
         textBox.Text = data;
     }
     catch (Exception ex)
     {
         MessageBox.Show($"加载失败: {ex.Message}");
     }
     finally
     {
         progressBar.Visible = false;
         btnLoad.Enabled = true;
     }

    }

来详细分析这段代码的执行顺序和执行所在线程:

执行顺序分析

  1. 用户点击按钮​ → UI线程

  2. 执行同步代码段

    • progressBar.Visible = true→ UI线程

    • btnLoad.Enabled = false→ UI线程

  3. 遇到await表达式

    • 启动GetStringAsync()异步操作 → 后台线程

    • 方法在此暂停控制权返回给调用者

  4. 异步操作完成后

    • 自动回到UI线程上下文

    • 继续执行await后面的代码

  5. 更新UI

    • textBox.Text = data→ UI线程
  6. 异常处理/清理

    • catch或finally块 → UI线程

线程切换示意图

UI线程: [点击] → [显示进度条] → [禁用按钮] → [暂停等待] → [恢复] → [更新文本框] → [隐藏进度条] ↓ 后台线程: [HTTP请求执行]...

关键线程信息

代码段 执行线程 说明
progressBar.Visible = true UI线程 同步执行
btnLoad.Enabled = false UI线程 同步执行
await httpClient.GetStringAsync() 后台线程池 I/O完成端口线程
textBox.Text = data UI线程 自动回到原始上下文
finally块中的代码 UI线程 同步执行

重要特性

  1. 不会阻塞UI:await期间UI线程可以处理其他消息

  2. 自动线程上下文恢复:await完成后自动回到UI线程

  3. 异常处理安全:任何异常都会在UI线程的catch块中处理

取消操作

使用 CancellationToken

复制代码
public async Task<string> DownloadWithCancelAsync(string url, 
    CancellationToken cancellationToken = default)
{
    using var client = new HttpClient();
    
    // 传递取消令牌
    HttpResponseMessage response = await client.GetAsync(url, cancellationToken);
    response.EnsureSuccessStatusCode();
    
    return await response.Content.ReadAsStringAsync();
}

// 使用示例
public static async Task Main()
{
    var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); // 5秒后取消
    
    try
    {
        var result = await DownloadWithCancelAsync("https://example.com", cts.Token);
        Console.WriteLine(result);
    }
    catch (OperationCanceledException)
    {
        Console.WriteLine("操作被取消");
    }
}
相关推荐
子兮曰1 天前
async/await高级模式:async迭代器、错误边界与并发控制
前端·javascript·github
恋猫de小郭1 天前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
GIS之路1 天前
ArcGIS Pro 中的 Notebooks 入门
前端
IT_陈寒1 天前
React状态管理终极对决:Redux vs Context API谁更胜一筹?
前端·人工智能·后端
晨星shine1 天前
GC、Dispose、Unmanaged Resource 和 Managed Resource
后端·c#
Kagol1 天前
TinyVue 支持 Skills 啦!现在你可以让 AI 使用 TinyVue 组件搭建项目
前端·agent·ai编程
柳杉1 天前
从零打造 AI 全球趋势监测大屏
前端·javascript·aigc
simple_lau1 天前
Cursor配置MasterGo MCP:一键读取设计稿生成高还原度前端代码
前端·javascript·vue.js
睡不着先生1 天前
如何设计一个真正可扩展的表单生成器?
前端·javascript·vue.js
天蓝色的鱼鱼1 天前
模块化与组件化:90%的前端开发者都没搞懂的本质区别
前端·架构·代码规范