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

使用委托实现异步回调的疑问:代码为何同步执行?

问题分析与解决方案

你的核心误区是把委托回调和异步执行划了等号——委托本质只是一种能传递方法引用的类型,它本身不会自动开启新线程,默认就是同步执行的。你的代码里所有逻辑都在主线程按顺序跑,所以才会出现输出顺序和预期不符的情况。

现有代码的执行流程

  1. 主线程打印 Starting long operation...
  2. 调用 DoLongOperation,主线程执行 Thread.Sleep(5000),直接被阻塞5秒,期间完全没法执行后续代码
  3. 5秒后执行回调 LongOperationCallback,打印结果
  4. 回到Main方法,才打印 Continuing execution while long operation runs...

这就是为什么你看到的输出顺序和预期相反——主线程被耗时操作卡死了,根本没法"一边等一边执行后续代码"。

如何改成真正的异步回调

要实现你想要的"主线程不阻塞,耗时操作完成后通知"的效果,必须主动把耗时操作放到独立的执行上下文(比如Task或线程)中。

方案1:用Task.Run开启异步任务

using System;
using System.Threading.Tasks;

class Program
{
    delegate void MyDelegate(int result);

    static void Main()
    {
        Console.WriteLine("Starting long operation...");
        // 把耗时操作包装到Task里,交给线程池执行
        Task.Run(() => DoLongOperation(LongOperationCallback));
        Console.WriteLine("Continuing execution while long operation runs...");
        Console.ReadLine();
    }

    static void DoLongOperation(MyDelegate callback)
    {
        System.Threading.Thread.Sleep(5000);
        callback(42);
    }

    static void LongOperationCallback(int result)
    {
        Console.WriteLine($"Long operation completed with result: {result}");
    }
}

方案2:现代C#推荐的async/await方式(更简洁)

不需要自定义委托,用Task直接返回结果:

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        Console.WriteLine("Starting long operation...");
        // 启动异步任务,主线程继续执行后续代码
        var longTask = DoLongOperationAsync();
        Console.WriteLine("Continuing execution while long operation runs...");
        
        // 等待任务完成并获取结果
        int result = await longTask;
        Console.WriteLine($"Long operation completed with result: {result}");
        Console.ReadLine();
    }

    static async Task<int> DoLongOperationAsync()
    {
        // 用Task.Delay替代Thread.Sleep,不会阻塞线程
        await Task.Delay(5000);
        return 42;
    }
}

关键知识点

  • 委托只是传递方法的工具,和异步没有必然联系;同步/异步取决于你在哪里执行委托指向的方法
  • 要实现异步回调,核心是让耗时操作脱离主线程执行,避免阻塞
  • 现代C#优先使用Task和async/await,比手动操作线程或旧版BeginInvoke更安全、易维护

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:22:59