从AppDomain卸载.DLL所需的帮助 – 即使使用ShadowCopy仍然无法正常工作

我正在尝试执行以下操作。 应用程序A是“母亲应用程序”。 它保持开放。 App B只是一个.DLL,我写了一些从App A中指定的接口派生的类。

然后,从App A,我将从App B“导入”类并在其中运行方法。 我希望能够动态更改App B(更改代码并重新编译)并使用App A中的新代码。

我在App B中有一个后编译命令,它将新的.DLL复制到App A目录。 应用A创建一个新的AppDomain并使用ShadowCopying。 我认为这就足够了,但是当我尝试重新编译和复制App B的新.DLL时,它表示该文件正在使用中且无法覆盖。

这是我现在的代码:

App A(代码中的TestServer):

namespace TestServer { public interface IRunnable { void Run(); } class Program { static void Main(string[] args) { AppDomainSetup setup = new AppDomainSetup(); setup.ApplicationName = "DemoApp"; setup.ApplicationBase = Environment.CurrentDirectory; setup.ShadowCopyDirectories = Environment.CurrentDirectory; setup.ShadowCopyFiles = "true"; int _domain = 1; while (true) { string typeName = Console.ReadLine(); AppDomain appDomain = AppDomain.CreateDomain("DemoDomain" + _domain, null, setup); IRunnable runner = appDomain.CreateInstanceFromAndUnwrap("TestClient.dll", typeName) as IRunnable; runner.Run(); AppDomain.Unload(appDomain); _domain++; } } } } 

App B(代码中的TestClient):

 namespace TestClient { public class TestRunner : TestServer.IRunnable { public void Run() { Console.WriteLine("RUNNING"); } } public class Bob : TestServer.IRunnable { public void Run() { Console.WriteLine("BOB"); } } } 

我已经读过,如果您使用来自其他应用程序域的内容,那些应用程序域可以自动加载.DLL或其他内容。 在这种情况下,我担心使用接口会导致基本AppDomain加载.DLL,从而将其锁定。

我该如何解决这个问题?是否有更好的设置?

注意:我已更新我的代码,它仍然产生相同的结果。

您的代码仍然在母AppDomain中运行,因为您将组件和类型拉入其中。 任何代码都应该在衍生域中运行。 我已经展示了一种在我的网站上设置类似内容的方法 : 在不同的AppDomain中启动代码的简单方法

我不是百分百肯定的,但这肯定是你必须采取的一步

更新

就那里提出的解决方案而言,运行器的实例化将发生在DomainLifetimeHook的inheritance者中。 显示的基础结构确保Start和Stop方法在AppDomainExpander类创建的AppDomain中运行。 Expander是创建新域的类,因此您的域设置应该放在域的Create方法中。

主要问题是你在哪里:

 Type type = assm.GetType("TestClient." + typeName); 

这发生在App A的主AppDomain中,结果是主AppDomain锁定App B的程序集.dll

flq对他博客文章的回答中的链接应该适合你。

只要打开ObjectHandle,就必须将类型加载到主appdomain中。 要正常工作,您需要对未解包的ObjectHandle进行操作。