异步编程不能提升CPU密集型任务性能,仅优化I/O等待;ConfigureAwait(false)在类库中必须使用以防死锁;异常堆栈易失真需手动包装;async void仅限UI事件处理;跨框架兼容性细节需谨慎。

异步编程不会自动提升 CPU 密集型任务的性能
很多人误以为 async/await 能让计算变快,其实它只优化 I/O 等待时间。比如对一个大数组做排序、图像处理或加密解密,用 Task.Run(() => HeavyComputation()) 包裹后,只是把工作扔到线程池里执行,并不减少总耗时,还增加了调度开销和上下文切换成本。
- 真正适合
async的场景:HTTP 请求(HttpClient.GetAsync)、文件读写(File.ReadAllTextAsync)、数据库查询(DbCommand.ExecuteReaderAsync)——这些本质是等待操作系统完成 I/O,期间线程可被复用 - 若强行把纯计算逻辑标记为
async且不配合Task.Run,编译器会警告“此 async 方法缺少 await”,运行时也仍是同步阻塞 - 高频调用小计算任务时,
Task.Run反而比直接同步执行更慢,因为线程池排队 + 状态机分配有额外开销
ConfigureAwait(false) 不是可有可无的配置项
在类库或底层工具方法中漏掉 ConfigureAwait(false),可能引发死锁或 UI 响应卡顿。它的作用是告诉运行时:await 完成后**不要强制回调回原始同步上下文**(比如 WinForms 的 UI 线程、ASP.NET Classic 的 HttpContext)。
- ASP.NET Core 默认没有
SynchronizationContext,所以多数情况下不加也不会出问题;但 ASP.NET Framework 或 WPF/WinForms 项目里,如果在 UI 线程调用GetAwaiter().GetResult()或错误地用了.Result,就极易死锁 - 类库作者必须默认加
ConfigureAwait(false),否则使用者在非 UI 环境引用该库时,可能因意外捕获上下文导致性能下降甚至异常 - 只有明确需要回到原上下文时才不加——比如更新 WPF 的
TextBox.Text,必须在 UI 线程执行
异常堆栈容易丢失原始位置
异步方法抛出异常后,堆栈信息会包含状态机内部方法(如 MoveNext),原始调用点可能被掩盖。尤其在多层 await 链路中,InnerException 层级变深,调试时第一眼看不到出错的真实行号。
AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。它不是新的编程语言,而是一种使用现有标准的新方法,最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容,不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。《php中级教程之ajax技术》带你快速
- 使用
try/catch捕获异常时,别只看e.ToString(),要逐层检查e.InnerException - .NET 5+ 支持
await using和更清晰的异常传播,但旧项目若还在用 .NET Framework 4.7.2,建议在关键异步入口处手动包装异常:try { await DoSomethingAsync(); } catch (Exception ex) { throw new InvalidOperationException("调用 DoSomethingAsync 失败", ex); } - 单元测试中用
Assert.ThrowsAsync而不是() Assert.Throws,否则会误判为未抛异常()
async void 是仅限事件处理程序的危险选择
async void 方法无法被 await,异常会直接炸到 SynchronizationContext 或进程级,极难捕获。它唯一合理用途是 UI 事件处理器(如 Button_Click)。
- 永远不要在业务逻辑、工具方法、API 接口里写
async void;应该统一用async Task - Web API 控制器中返回
Task是标准做法;写成async void会导致请求提前结束、日志缺失、监控失效 - 测试
async void方法几乎不可能——没有返回值,没地方await,只能靠超时或副作用判断,可靠性极低
ValueTask 在 .NET Core 2.1+ 才稳定支持,老项目升级时若盲目替换 Task,可能引入隐式装箱或生命周期错误;还有 async 方法里用 lock 会编译失败,必须改用 SemaphoreSlim.WaitAsync。这些都不是理论问题,而是上线后才暴露的坑。









