async/await 启用异步、非阻塞代码,使其读起来像同步代码。它对 I/O 密集型工作(数据库、网络、文件访问)至关重要 — 让程序在等待缓慢操作时能处理其他工作(或请求),提高响应性和可扩展性。
基本模式
{
client = HttpClient();
result = client.GetStringAsync(url);
result;
}
data = GetDataAsync();
async 方法返回 Task(或 Task<T>),而 await 会暂停该方法直到被等待的操作完成 — 不会阻塞线程。在等待期间,线程被释放以执行其他工作(处理其他请求、保持 UI 响应)。代码从上到下读起来像同步代码,尽管实际上是异步的。
❌ synchronous I/O — the thread BLOCKS, doing nothing while waiting (wastes resources)
✅ async I/O — the thread is RELEASED during the wait, serving other work
→ A web server using async can handle far more concurrent requests with fewer threads.
// ❌ sequential — total time = sum of both
var a = await GetAAsync();
var b = await GetBAsync();
// ✅ concurrent — start both, then await both (total = max, not sum)
Task<string> taskA = GetAAsync();
Task<string> taskB = GetBAsync();
await Task.WhenAll(taskA, taskB); // run independent operations in parallel
使用 Task.WhenAll 并发等待多个独立操作 — 当操作不相互依赖时,性能会大幅提升。
✓ Use async "all the way" — async methods called by async methods
✓ Name async methods with the Async suffix (convention)
✗ AVOID async void (except event handlers) — exceptions are unobservable, can crash
✗ AVOID blocking on async (.Result / .Wait()) — can DEADLOCK; await instead
✓ async is for I/O-bound work; for CPU-bound parallelism use Task.Run / Parallel
async/await 是现代 C# 中基础且广泛使用的特性 — 对于构建响应迅速、可扩展的应用程序至关重要,因此理解它很重要。
其核心价值在于实现非阻塞异步 I/O:对于 I/O 密集型操作(数据库查询、HTTP 调用、文件访问),async/await 在等待期间释放线程以执行其他工作,而不是空闲地阻塞 — 这大幅提高了可扩展性(Web 服务器可以用更少的线程处理更多的并发请求)和响应性(在执行缓慢操作时 UI 保持响应)。
关键在于,它在保持代码可读性的前提下实现了这一点(代码读起来像同步代码尽管实际是异步的),避免了旧版异步方法的回调复杂性。
理解该模式(async 方法返回 Task/Task<T>,await 用于非阻塞等待)、使用 Task.WhenAll 并发运行操作(对独立操作是显著的性能提升),特别是理解常见陷阱(在事件处理程序外避免 async void — 其异常可能导致应用崩溃;不要用 .Result/.Wait() 阻塞异步代码 — 可能导致死锁;始终使用 async "全栈")对于编写正确、高性能的异步 C# 代码至关重要。
由于 async/await 在现代 C# 中无处不在(ASP.NET Core、EF Core 以及大多数 I/O API 都是异步优先),并且由于误用会导致真实问题(死锁、崩溃、可扩展性差),掌握它 — 该模式、使用 WhenAll 实现并发,以及关键陷阱 — 是现代 C# 开发中至关重要的、频繁应用的知识,也是一个常见且重要的面试话题。