调试和释放模式之间的DLL加载差异

时间:2009-02-23 05:58:17

标签: c# visual-studio-2005

使用Visual Studio 2005。

这是一个有趣的。

要重现,请使用Windows应用程序和类创建新的解决方案 库。

在类库中,像这样定义类:

public class SomeClassInDLL
{
    public string DoSomething()
    {
        return DateTime.Now.ToString();
    }
}

获取Windows应用程序以引用类库。添加一个按钮,然后添加 这段代码:

    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            MessageBox.Show("about to call DoSomething");
            string ret = DoCall();
            MessageBox.Show(ret);
        }
        catch (Exception ex)
        {
            MessageBox.Show("error : " + ex.GetType().ToString() + " " + ex.Message);

        }
    }

    private string DoCall()
    {
        SomeClassInDLL c1 = new SomeClassInDLL();
        return c1.DoSomething();
    }

1)在Debug和Release模式下编译应用程序。 (进入bin \ Debug和 bin \ Release目录)

2)关闭visual studio,从Windows资源管理器运行Windows应用程序

3)单击按钮1。

4)当“即将调用DoSomething”对话框出现时,在Windows资源管理器中,尝试删除引用的dll文件。

5a)如果您在步骤2中运行调试模式版本:您可以删除dll 文件成功。这是我所期望的,因为dll正在被调用 在DoCall函数内部,而不是直接在button1_Click。

5b)如果您在步骤2中运行了发布模式版本:您无法删除 dll文件,因为它似乎被应用程序锁定。

==

5a)是我所期望的行为,因为dotnet是1.1天。有任何想法吗 为什么5b)似乎比必要的更早锁定dll?与此有关 优化也许? 是否在某处解释了这种dll加载行为?

TIA。

1 个答案:

答案 0 :(得分:1)

在发布模式下,可能会将DoCall功能内联到按钮单击事件处理程序中。

这意味着类型加载器需要更早地了解SomeClassInDll(因此锁定了dll)

请注意,依赖此行为是危险的,可以通过反射,内联启发式更改或类型加载器中的更改(例如,依赖方法的推测性jit加载)轻松触发类型加载 - 尽管这不太可能)