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

C#调用异步方法报错:无法从程序集加载类型'<deleteCommands>d__2'

解决C#异步调用中“Could not load type 'd__2' from assembly”错误

嘿,作为PHP开发者刚接触C#异步编程,确实容易踩一些框架特有的坑,我来帮你拆解这个问题~

错误原因分析

这个错误通常和异步方法编译生成的状态机类型加载失败有关,而你的代码里的async static void写法是核心诱因之一:

  • C#的async方法会被编译器编译成一个包含状态机的隐藏类(比如<deleteCommands>d__2就是这个自动生成的类名),如果方法签名是async void,编译器生成的状态机逻辑会有特殊处理,很容易因为无法被正确追踪、加载而抛出类型找不到的错误。
  • 另外,async void本身就是C#异步编程中的反模式(仅推荐用于事件处理程序),它无法被调用者等待,异常也无法被正常捕获,会进一步引发各种奇怪的运行时问题。

具体解决方案

1. 把async static void改为async static Task

这是最关键的一步,修改方法签名后,编译器会生成正确的可追踪的状态机类型,同时让调用者可以正常等待方法完成:

public async static Task DeleteCommands(List<int> commandIds) 
{
    Tebex.logWarning("Async Delete....");
    // 这里不推荐用Task.Run包装同步操作,换成真正的异步IO逻辑
    using var httpClient = new HttpClient();
    string url = "http://www.example.com/" + "qu..."; // 补全你的URL拼接逻辑
    // 用HttpClient的异步方法发起请求,替代同步包装
    var response = await httpClient.GetAsync(url);
    
    // 后续可以添加响应处理逻辑,比如:
    if (response.IsSuccessStatusCode)
    {
        var content = await response.Content.ReadAsStringAsync();
        // 处理返回内容
    }
}

2. 避免用Task.Run包装IO密集型操作

你原来的代码用Task.Run把HTTP请求包装成异步,这是典型的伪异步操作——它会占用线程池线程,完全浪费了异步IO的优势。直接使用HttpClient的异步方法(比如GetAsync、PostAsync)才是正确的异步IO实现。

3. 排查编译与部署问题

如果修改签名后还是报错,可以试试这些操作:

  • 清理解决方案并重新编译(清除编译缓存,避免旧的状态机类残留)
  • 检查项目的目标框架版本:确保使用的是.NET Framework 4.5+或.NET Core/.NET 5+,这些版本对async/await支持更完善
  • 确认程序集部署完整:如果是部署到服务器/容器,检查所有依赖的程序集是否都正确上传

调用修改后的方法

修改完方法后,调用的时候也要用await来等待它完成(如果调用者本身也是async方法):

// 在另一个async方法中调用
await DeleteCommands(commandIdList);

如果是在非async的同步方法中调用,可以用.Wait()或者.GetAwaiter().GetResult()(注意死锁风险,建议尽量用async链)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:35:36