AppDomain.Unload() 如何中止线程?

Posted

技术标签:

【中文标题】AppDomain.Unload() 如何中止线程?【英文标题】:How does AppDomain.Unload() abort the threads? 【发布时间】:2011-06-23 09:07:18 【问题描述】:

根据多个资源(例如MSDN和CLR通过C#),当我们调用AppDomain.Unload(userDomain)时,userDomain中的线程将被强制抛出ThreadAbortException,直到我们调用Thread.ResetAbort才能停止.所以我尝试了下面的代码来证明我的理解。在默认域中创建的一个线程运行以下代码来调用在另一个域(即用户域)中创建的 FooType 的 foo 对象

    void ThreadRun(object o)
           
           try 
           
                // this call will cross the App domain;
                foo.Run();
            
            catch (AppDomainUnloadedException EXP)
                                
                 Console.WriteLine("Get appdomain unload exception");
            
            catch (ThreadAbortException EXP)
                                
                Console.WriteLine("Get threadAbortException in ThreadRun");
            
            Console.WriteLine("Strange, this thread is still alive");
     

Foo.Run 代码如下所示(它什么都不做,只是休眠)

public class FooType : MarshalByRefObject 
  public void Run()
  
    try
    
        Console.WriteLine("Foo.Run is running at " + Thread.GetDomain().FriendlyName);
        Thread.Sleep(TimeSpan.FromSeconds(1500));
    
    catch (ThreadAbortException)
    
        Console.WriteLine("get thread abort exception");
    
  

如果我尝试卸载 userDomain,我很惊讶 ThreadAbortException 仅在 FooType:Run() (在 userDomain 中)中被捕获,而不是在 ThreadRun() 方法(在 defaultDomain 中)中被捕获。而 ThreadRun() 只会得到 AppDomainUnlo adException 然后继续运行。

如果我尝试在不卸载域的情况下直接中止线程,则两个地方都会出现 ThreadAbortException。

我想知道这种差异是否应该发生?非常感谢

【问题讨论】:

也许当你中止 userDomain 时,defaultDomain 可能会收到一个包装异常(内部异常是 ThreadAbortException。尝试改用 catch (Exception ex) 并检查是否存在不同的异常抛出什么是InnerException。我想在这种情况下会抛出AppDomainUnloadedException 【参考方案1】:

当您卸载 userDomain 时,当前在该域中工作的线程会收到 AbortException。但是,同样的线程也“在”另一个 AppDomain(主)。将 AppDomains 作为数据分隔符,而不是执行分隔符,CLR 无法中止产生多个 AppDomains 的线程。这就是为什么你只会得到 UnloadedException。

当您调用 Thread.Abort 时 - 您正在明确中止线程的执行,无论它当前所处的 AppDomain 是什么。

无论如何,当您只想卸载一些 AppDomain 时,您不希望线程被中止。

【讨论】:

以上是关于AppDomain.Unload() 如何中止线程?的主要内容,如果未能解决你的问题,请参考以下文章

AppDomain.Unload 抛出终结器?

AppDomain.Unload 问题

进程和 AppDomain 加载/卸载

即使我卸载 appdomain,我的 dll 也不会卸载

assembly 需要 unload 和 update 的时候怎么办?

C#动态加载dll 时程序集的卸载问题