如何防止在.NET中智能加载DLL?

时间:2011-03-24 15:49:35

标签: c# .net dll

我对正在处理的程序有一些问题。它由2个DLL组成,dll A引用dll B. Dll A包含一个公共方法,其中第一个动作(在实例化B中的任何类之前)是检查一些网络位置以查看是否有新版本的dll B可用。如果是这样,它将它下载到当前B的相同位置,这应该不是问题,因为B没有实例化。可悲的是,它是实例化的,所以我得到一个错误,它已经被拥有A并且无法替换的进程引用。

您是否已经知道它已被引用的原因,以及是否有任何解决方案可以避免这种情况?

public class L10nReports//Class in DLL A
{
    public L10nReports() //constructor
    {
    }

    //only public method is this class
    public string Supervise(object projectGroup, out string msg)
    {
        //Checks for updates of dll B and downloads it if available. And fails.
        manageUpdate();

        //first instanciation of any class from dll B
        ReportEngine.ReportEngine engine = new ReportEngine.ReportEngine();

        string result = engine.Supervise(projectGroup, out msg);

        return result;
    }

2 个答案:

答案 0 :(得分:6)

当您的“Supervise”方法被JIT时,将加载B dll。这里的问题是,第一次加载DLL时,需要B.dll中某些类型的类型信息 not 第一次实例化对象时。

因此,在引用B.dll中的任何类型之前,以及在调用任何在B.dll中使用类型的方法之前,必须检查更新。

public class L10nReports//Class in DLL A
{
    public L10nReports() //constructor
    {
    }


    //only public method is this class
    public string Supervise(object projectGroup, out string msg)
    {
       manageUpdate();
       return SuperviseImpl(projectGroup, out msg);
    }


    private string SuperviseImpl(object projectGroup, out string msg)
    {
        //first instanciation of any class from dll B
        ReportEngine.ReportEngine engine = new ReportEngine.ReportEngine();

        string result = engine.Supervise(projectGroup, out msg);

        return result;
    }

答案 1 :(得分:5)

Jit编译器需要加载Dll B,以便检查/验证Supervise方法。

将对Dll B的调用移至另一种方法,prevent this method from being inlined[MethodImpl(MethodImplOptions.NoInlining)])。否则,您可能会从调试模式切换到释放模式。

如果我没记错,内联不会用于Debug编译代码,但是发布代码可能会内联被调用的方法,在检查之前使抖动加载Dll B.

    //only public method is this class
    // all calls to dll B must go in helper function
    public string Supervise(object projectGroup, out string msg)
    {
        //Checks for updates of dll B and downloads it if available. And fails.
        manageUpdate();

        return SuperviseHelper(projectGroup, out msg);
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    public string SuperviseHelper(object projectGroup, out string msg) {
        //first instanciation of any class from dll B
        ReportEngine.ReportEngine engine = new ReportEngine.ReportEngine();

        string result = engine.Supervise(projectGroup, out msg);

        return result;
    }