【发布时间】:2011-08-11 23:28:43
【问题描述】:
我有一个应用程序,它将一个 DLL (UserControlLibrary) 复制到它自己的 Debug/Release 文件夹并使用此代码加载它:
AppDomain appDomain = AppDomain.CreateDomain("MyDomain");
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "DLLs (*.dll)|*.dll";
if (dialog.ShowDialog().Value)
{
string newLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\" + dialog.SafeFileName;
File.Copy(dialog.FileName, newLocation, true);
Assembly assembly = appDomain.Load(AssemblyName.GetAssemblyName(newLocation));
UserControl userControl = (UserControl) assembly.CreateInstance("WpfControlLibrary1.UserControl1");
}
我现在将该 UserControl 添加到 Grid 中:
grid.Children.Add(userControl);
工作正常。现在我尝试使用以下方法卸载 DLL:
AppDomain.Unload(appDomain);
grid.Children.Clear();
如果我现在尝试使用上述代码再次加载 DLL(因为它同时发生了变化),我会收到一条错误消息,告诉我文件正在使用中 (File.Copy)。
我已经阅读了很多内容,我的猜测是我不能像以前那样使用 UserControl(因为它会加载到主 AppDomain 中)。我必须如何更改代码才能使其正常工作?
我也阅读了很多关于使用 MarshalByRefObject 的内容,但不幸的是我无法在这个项目中实现它。上面代码的示例或修改会很好。
编辑:
从我目前读到的 cmets(尤其是 svick)看来,我必须使用“AppDomain.CreateInstanceAndUnwrap”而不是“AppDomain.Load”。 我之前在寻找解决方案时已经看到了这种方法,但正如 svick 提到的那样,这不起作用,因为 UserControl 不能从 MarshalByRefObject 继承。
有人知道另一种方法吗?
【问题讨论】:
-
请不要在标题前加上“C#”。我们在Stack Overflow 上使用标签。
-
您的类型可能跨越了域边界,因此它们将卡在“主”运行的应用程序域中。使用
MarhshalByRefObject建议以及远程对象的通用接口。这很难,但一旦你掌握了它,你就会明白 :) 顺便说一句,这是学习远程处理的一个很好的练习。 -
UserControl 不能从 MarhshalByRefObject 继承...?