You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#异步代码异常:两段Main方法请求服务端分别偶发失败和卡死

两段代码问题原因解析

第一段 async void Main 偶发请求失败原因

  • async void 方法没有返回可被跟踪的 Task 对象,运行时无法等待这类方法执行完成
  • 作为程序入口的 Main 方法被标记为 async void 时,代码执行到 await GetAsync 行就会立刻将控制权交回给程序启动的运行时,运行时会判定 Main 已经执行完毕,直接启动进程退出流程
  • 只有在进程完全终止前,网络请求刚好完成全部逻辑,才会表现为请求成功,否则请求会被中途中断,所以会出现有时成功有时失败的现象
    注:C# 7.1 及以上版本已经支持 async Task Main 的入口写法,专门用于解决异步入口的等待问题

第二段 .Wait() 无限挂起原因

这是典型的异步同步上下文死锁问题,触发流程如下:

  • 默认情况下(桌面应用、.NET Framework ASP.NET 场景),异步方法执行时会捕获当前的同步上下文,这类同步上下文是单线程独占的,同一时间只能有一个操作在上下文上执行
  • 调用 .Wait() 时会直接阻塞当前主线程,等待 GetAsync 返回的 Task 执行完成
  • GetAsync 的网络IO请求完成后,需要回到之前捕获的同步上下文执行后续收尾逻辑,但此时主线程已经被 .Wait() 阻塞,无法释放上下文给异步任务使用,就形成了「主线程等待Task完成,Task等待主线程释放上下文」的循环死锁,程序会永久挂起,请求自然也无法正常完成
    临时规避可改成 new HttpClient().GetAsync("http://localserver").ConfigureAwait(false).Wait(),但更推荐全程使用 await 做异步等待,不要混用同步阻塞方法

内容的提问来源于stack exchange,提问作者KittyDotNet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 11:54:03