Z
ZHANK
编程在线教程C# 教程async/await 异步编程
异步编程

async/await 异步编程

Task<T>/async/await、不阻塞线程、ConfigureAwait、async void 陷阱

async/await 异步编程

C# 的 async/await 是异步编程的黄金标准——用同步写法写异步代码,不阻塞线程。

学完本章你将: 掌握 Task/async/await、不阻塞线程、ConfigureAwait。


异步方法

csharp
// 同步写法(阻塞线程)
string DownloadSync(string url)
{
    using var client = new HttpClient();
    return client.GetStringAsync(url).Result;  // ❌ 死锁风险
}

// 异步写法(不阻塞线程)
async Task<string> DownloadAsync(string url)
{
    using var client = new HttpClient();
    return await client.GetStringAsync(url);
}

// 调用
var html = await DownloadAsync("https://example.com");
Console.WriteLine(html[..100]);

async void 陷阱

csharp
// ❌ async void —— 异常无法被捕获!
async void BadHandler(object sender, EventArgs e)
{
    await Task.Delay(1000);
    throw new Exception("这个异常会崩溃进程!");
}

// ✅ 事件处理器中唯一可接受 async void
// ✅ 其余一律用 async Task
async Task GoodMethod()
{
    await Task.Delay(1000);
}

ConfigureAwait

csharp
// 库代码中建议使用 ConfigureAwait(false)
// 避免回到原始同步上下文(提升性能,防止死锁)
var html = await client.GetStringAsync(url)
    .ConfigureAwait(false);

// UI 应用(WPF/WinForms)不要用 ConfigureAwait(false)
// 需要在 UI 线程更新控件时