async方法必须返回Task或Task,否则编译报错;await只能在async方法内使用;禁用.Result/.Wait()防死锁;类库中推荐ConfigureAwait(false)。

async 方法必须返回 Task 或 Task
不满足这个条件的 async 方法在编译时就会报错,比如返回 void(除事件处理器外)或 int。这是最基础也最容易忽略的约束。
-
async Task用于无返回值的异步操作,如async Task SaveAsync() -
async Task用于有返回值的异步操作,调用后可用await获取string结果 - 避免写
async void DoSomething()—— 无法被等待、异常会直接崩掉线程、难以测试
await 只能在 async 方法内部使用
试图在普通方法里写 await SomeAsyncMethod() 会触发编译错误 CS4032:“The 'await' operator can only be used within an async method.”
- 不是“加个
async就行”,还要同步改返回类型(见上一条) - 如果调用链顶端是 UI 事件(如按钮点击),可合法用
async void,但仅限这一层 - Web API 控制器中应始终用
async Task,而非async void
不要用 .Result 或 .Wait() 阻塞异步方法
在 ASP.NET Core 或 WinForms 中调用 task.Result 或 task.Wait() 极易引发死锁,尤其在有同步上下文(SynchronizationContext)的环境里。
AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。它不是新的编程语言,而是一种使用现有标准的新方法,最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容,不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。《php中级教程之ajax技术》带你快速
- 典型死锁现象:UI 线程卡住 / HTTP 请求永远不返回 / 日志停在某一行不动
- 替代方案:把调用点也改成
async+await,让整个调用链异步穿透 - 实在无法改(如老代码或第三方同步接口),可用
Task.Run(() => SomeAsyncMethod()).Result绕过上下文,但这是权宜之计,不是设计选择
ConfigureAwait(false) 在类库中值得默认添加
在非 UI、非 ASP.NET 传统管线(如 .NET Core Web API、类库、工具函数)中,await task.ConfigureAwait(false) 能避免不必要的上下文捕获,提升性能并防止潜在死锁。
- ASP.NET Core 默认无 SynchronizationContext,所以
ConfigureAwait(false)影响不大,但加了也没坏处 - 在 NuGet 类库项目中建议统一加上,避免下游使用者踩坑
- UI 层(WPF/WinForms)需要更新控件时,不能加
ConfigureAwait(false),否则会抛出跨线程访问异常
public async Task异步的本质不是“多线程”,而是“不阻塞当前线程”。很多人一上来就想着开新线程,反而绕远了。真正容易出问题的地方,往往藏在返回类型和上下文切换这两处。FetchDataAsync() { var response = await httpClient.GetAsync("https://api.example.com/data") .ConfigureAwait(false); // 类库中推荐 return await response.Content.ReadAsStringAsync() .ConfigureAwait(false); }









