AppDomains、卸载和 ThreadAbortException

Posted

技术标签:

【中文标题】AppDomains、卸载和 ThreadAbortException【英文标题】:AppDomains, Unloading, and ThreadAbortException 【发布时间】:2014-03-23 17:53:24 【问题描述】:

我是第一次尝试使用 AppDomains,但我发现自己有点迷茫。

这是我所做的: 我有一个控制台应用程序,它实例化一个 Bootstrapper 类并调用 Bootstrapper.Bootstrap。

这个类看起来像这样:

    public class Bootstrapper : MarshalByRefObject
    
        private static AppDomain SecondaryAppDomain;
        private Bootstrapper _secondaryDomainBootstrapper;
        public Robot CurrentlyRunningRobot;
        public Bootstrapper OwningBootstrapper;

        public Bootstrapper()
        

        

        public void Bootstrap()
        
            InitializeSecondaryAppDomain();
            RunInSecondaryAppDomain();
        

        private void DestroySecondaryAppDomain()
        
            AppDomain.Unload(SecondaryAppDomain);
        

        private static int initCount = 0;

        private static void InitializeSecondaryAppDomain()
        
            initCount++;
            SecondaryAppDomain = AppDomain.CreateDomain("SecondaryAppDomain" + initCount);
        

        private void RunInSecondaryAppDomain()
        
            _secondaryDomainBootstrapper =
                (Bootstrapper)
                    SecondaryAppDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName,
                        "myNamespace.Bootstrapper");
            _secondaryDomainBootstrapper.OwningBootstrapper = this;
            _secondaryDomainBootstrapper.Initialize(Args);
                

        private void Initialize(string[] args)
        
            //Do some stuff...
            //Start() returns Task<Robot>
            var robot = Initializer.Start();
            CurrentlyRunningRobot = robot.Result;
            CurrentlyRunningRobot.HardResetRequested += OnHardResetRequested;
            robot.Wait();
        

        private void DoHardReset()
        
            DestroySecondaryAppDomain();
            InitializeSecondaryAppDomain();
            RunInSecondaryAppDomain();
        

        private void OnHardResetRequested(object sender, EventArgs e)
        
            OwningBootstrapper.DoHardReset();
        
    

意图是在辅助域中运行的任何东西都请求终止并重新启动。

不过,发生的情况是,当我调用 DestroySecondaryAppDomain()(从默认 AppDomain 中)时,我会遇到 ThreadAbortExceptions。

我一直在阅读一堆文档,这似乎很正常。我遇到的困难是为什么我似乎无法在我的默认 AppDomain 中处理它。

当辅助 AppDomain 被卸载时(在 DestroySecondaryAppDomain 中),我永远无法执行 DoHardReset 中的其余代码。我不明白什么(可能很简单)?

【问题讨论】:

如果是Serializable,这意味着程序集将跨越appdomain边界,如果不使用代理类,您将无法卸载它。编辑:通常MarshalByRefObject 类将实现一个独立的接口(可以在两个应用程序域中加载)。 谢谢。我不记得当我添加它时我在做什么,但它似乎没有必要,所以我已经删除了它。问:独立接口——它通常存在于单独的程序集中吗? 是的,接口在一个独立的程序集中。 我没有看到任何异常处理/跟踪卸载。您很可能会收到AppdomainUnloadException(如果您的第二个 AppDomain 没有及时关闭,这也是预期的)。 其实是一个ThreadAbortException。这是我不明白的一件事——为什么我的默认 AppDomain 中会出现 ThreadAbortException?我希望它发生在辅助 AppDomain 中,但我有点不希望它越过边界回到默认 AppDomain。 【参考方案1】:

长话短说,仍有代码在该 AppDomain 中执行。需要完全停止它才能成功卸载而不会出错。

【讨论】:

在调用AppDomain.Unload之前,您是如何知道代码何时完成的?

以上是关于AppDomains、卸载和 ThreadAbortException的主要内容,如果未能解决你的问题,请参考以下文章

跨 AppDomains 的 NLog 配置

几个appdomains调用相同的非托管DLL

传递给已卸载 AppDomain 的服务的内存泄漏

我的应用程序域无法卸载

AppDomains之间的通信

使用 appdomains 时无法设置同步上下文