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

如何让C#中DoSomething非阻塞等待async void方法DoMore执行完成?

问题分析与解决方案

原代码问题

你当前的代码里,DoMore用了async void返回类型,这种类型仅适用于事件处理程序,普通异步方法用它会导致调用者(DoSomething)无法跟踪其执行状态——所以DoSomething会直接跳过等待,继续执行后续代码,就出现了不符合预期的输出顺序。

而且你尝试的方案里用Task.Run(() => DoMore())完全没必要,反而额外创建了线程,违背了你的需求。

正确实现代码

要实现非阻塞等待且不额外开线程,只需要调整异步方法的返回类型,并正确使用await:

public class Example
{
    public async Task DoSomething()
    {
        Console.WriteLine("DoSomething Start:");
        // 直接await DoMore,无需额外包裹Task.Run
        await DoMore();
        Console.WriteLine("DoSomething End:");
    }

    public async Task DoMore()
    {
        Console.WriteLine("DoMore Start:");
        // 用Task.Delay替代Thread.Sleep+Task.Run,避免阻塞线程
        await Task.Delay(1000);
        Console.WriteLine("DoMore End:");
    }
}

关键调整点

  • 把async void换成async Task:async Task是普通异步方法的标准返回类型,调用者可以通过await等待它执行完成,这是实现非阻塞等待的前提。
  • 直接await异步方法:DoMore本身就是异步方法,直接await它不会创建额外线程,只会让DoSomething暂停执行,直到DoMore完成后再继续,完全符合非阻塞的要求。
  • 替换Task.Run(() => Thread.Sleep(1000))为Task.Delay(1000):Thread.Sleep会阻塞线程,而Task.Delay是真正的异步等待,不需要占用线程资源,更契合异步编程的设计。

调用时,在异步上下文里直接用await new Example().DoSomething()即可,输出顺序会和你预期的一致:

DoSomething Start:
DoMore Start:
DoMore End:
DoSomething End:

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:10:15