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

部分程序进入Main()前加载DLL触发FileNotFoundException的原因及解决方案

问题原因

CLR会在JIT编译方法时,提前加载该方法内部所有类型依赖的程序集,出现未进入Main就加载DLL的核心触发场景包括:

  • Main方法内直接引用了共享DLL中的类型,JIT编译Main方法时就会触发DLL加载,此时还没执行到你写的AssemblyResolve注册逻辑
  • Main方法所在类的静态字段、静态构造函数中使用了共享DLL的类型,类型初始化逻辑执行时机早于Main方法
  • 程序集层面的特性(Attribute)引用了共享DLL中的类型,程序集加载时就会触发依赖加载
解决方案

核心修改逻辑

保证所有对共享DLL类型的引用,都放在AssemblyResolve注册完成后再被JIT编译加载,具体操作如下:

  • 将所有用到共享DLL类型的业务逻辑,封装到独立的方法或类中,不要在Main方法、Main所在类的静态构造/静态字段中直接引用共享DLL的类型
  • Main方法仅保留AssemblyResolve注册逻辑,注册完成后再调用封装了业务逻辑的方法即可

代码示例

错误写法

// 该写法会触发提前加载DLL:Main方法直接引用了共享DLL的SharedDllClass类型,JIT编译Main时就会尝试加载DLL
class Program
{
    static void Main()
    {
        AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => 
        {
            // 你的共享DLL加载逻辑
            return null;
        };
        // 这里直接用到了共享DLL的类型
        SharedDllClass.Run();
    }
}

正确写法

// 该写法可避免提前加载:用到共享DLL的逻辑放在单独方法中,注册完成后才会被JIT编译
class Program
{
    static void Main()
    {
        AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => 
        {
            // 你的共享DLL加载逻辑
            return null;
        };
        // 注册完成后再调用业务方法
        RunBusiness();
    }

    static void RunBusiness()
    {
        SharedDllClass.Run();
    }
}

其他注意事项

  • 不要在Main方法所在类的静态字段初始化、静态构造函数中使用共享DLL的类型
  • 移除程序集层面引用了共享DLL类型的特性定义
  • 若使用C# 9及以上版本,也可将AssemblyResolve注册逻辑放到模块初始化器中,该逻辑会在Main方法执行前运行,也可解决提前加载问题,但兼容性弱于上述方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:45:03