使用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。
答案 0 :(得分:1)
在发布模式下,可能会将DoCall功能内联到按钮单击事件处理程序中。
这意味着类型加载器需要更早地了解SomeClassInDll(因此锁定了dll)
请注意,依赖此行为是危险的,可以通过反射,内联启发式更改或类型加载器中的更改(例如,依赖方法的推测性jit加载)轻松触发类型加载 - 尽管这不太可能)