0

0

c# async 和 await 详解

幻夢星雲

幻夢星雲

发布时间:2026-01-11 02:57:32

|

280人浏览过

|

来源于php中文网

原创

async/await 是异步编程模型,非多线程,核心是避免 IO 等待阻塞主线程且保持同步写法;必须返回 Task 或 Task,禁用 void(除 UI 事件);await 不开新线程,仅挂起方法并交出控制权;需确保调用链全异步,禁止在构造函数等处使用;ConfigureAwait(false) 防死锁,适用于类库与后台服务。

c# async 和 await 详解

async/await 不是多线程,也不是“自动提速”的魔法——它只是让 IO 等待不卡主线程,且代码写起来像同步一样直白。

async 方法必须返回 Task 或 Task,别用 void(除非 UI 事件处理)

返回 void 的 async 方法无法被 await,也无法传播异常,调试时会静默失败。只在 Windows Forms/WPF 的事件处理器中允许使用,例如:private async void button1_Click(...)。其他所有场景,一律用 TaskTask

  • Task:表示“有异步操作,但不返回值”(如保存日志、发送通知)
  • Task:表示“操作完成后返回一个 int”,函数体内直接 return 42;,编译器自动包装成 Task.FromResult(42)
  • 千万别写 async Task MyMethod() { await SomeAsync(); return; } —— 返回类型是 Task 就够了,return; 是冗余的

await 不会阻塞线程,但它会让方法“暂停并交出控制权”

当你写 await client.GetStringAsync(url),当前方法立即返回(比如返回一个未完成的 Task),调用方可以继续执行;等网络响应回来,后续代码才在合适的上下文(如 UI 线程或线程池线程)中恢复。关键点:

  • await 后面的对象必须是“可等待的”(实现 GetAwaiter(),通常是 TaskValueTask
  • 如果 await 的是已结束的 Task(比如 Task.FromResult("done")),不会真正暂停,直接往下走
  • await 不等于“新开线程”——HttpClient 的请求本身是 IO 完成端口驱动的,不占线程池线程

别在同步方法里“假装 await”:没有 async 就不能用 await

下面这段代码会编译报错:CS4032:The 'await' operator can only be used within an async method

PHP高级程序设计 模式 框架与测试(中文高清PDF版)
PHP高级程序设计 模式 框架与测试(中文高清PDF版)

享有盛誉的PHP高级教程,Zend Framework核心开发人员力作,深入设计模式、PHP标准库和JSON 。   今天,PHP已经是无可争议的Web开发主流语言。PHP 5以后,它的面向对象特性也足以与Java和C#相抗衡。然而,讲述PHP高级特性的资料一直缺乏,大大影响了PHP语言的深入应用。   本书填补了这一空白。它专门针对有一定经验的PHP程序员,详细讲解了对他们最为重要的主题

下载
public string GetData()
{
    var result = await httpClient.GetStringAsync("https://api.example.com"); // ❌ 编译不过
    return result;
}

正确做法是向上一层推:调用方也得是 async,形成“异步链条”:

public async Task GetDataAsync() // ✅ 加 async,改返回 Task
{
    var result = await httpClient.GetStringAsync("https://api.example.com"); // ✅ 合法
    return result;
}

// 调用处也要 await(或 .GetAwaiter().GetResult() —— 仅限测试/极少数阻塞场景)
public async Task HandleRequest()
{
    string data = await GetDataAsync(); // ✅
}
  • 禁止在构造函数、属性 getter/setter、终结器中用 async/await(语法不允许)
  • 不要为了“看起来异步”而强行加 Task.Run(() => SyncMethod()) 包装 CPU 密集型操作——这反而增加调度开销,应改用 Task.Run 显式卸载到线程池,且调用方需理解这是真多线程

常见陷阱:ConfigureAwait(false) 和 UI 线程死锁

在类库(如 NuGet 包)或后台服务中,建议对所有 await 加上 .ConfigureAwait(false)

var html = await httpClient.GetStringAsync(url).ConfigureAwait(false);
  • 默认 ConfigureAwait(true) 会尝试回到“原始上下文”(如 WinForms 的 UI 线程),若该上下文正被同步阻塞(比如调用了 .Result.Wait()),就会死锁
  • 类库不应假设调用方上下文,所以一律 false;UI 层(如 WPF 的 ViewModel)若需更新控件,则保留默认(即不写 ConfigureAwait),由框架自动调度回 UI 线程
  • ASP.NET Core 默认无同步上下文,ConfigureAwait(false) 影响不大,但加上更稳妥

最常被忽略的一点:async/await 的价值不在“快”,而在“不卡”。它解决的是资源等待时的线程空转问题,不是替代算法优化或数据库索引。写错一个 await 可能导致整个请求线程被占住,尤其在高并发 Web API 中——这种问题不会报错,只会悄悄拖慢吞吐量。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

533

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

51

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

194

2025.08.29

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

175

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

96

2025.11.27

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

479

2023.08.10

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

25

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.8万人学习

AngularJS教程
AngularJS教程

共24课时 | 2.5万人学习

CSS教程
CSS教程

共754课时 | 18.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号