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

时间:2011-06-23 09:07:19

标签: c# .net appdomain

根据muliple资源(例如,通过C#的MSDN和CLR),当我们调用AppDomain.Unload(userDomain)时,userDomain中的线程将被强制抛出ThreadAbortException,这不能是sttile untile我们称之为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。

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

1 个答案:

答案 0 :(得分:1)

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

当你调用Thread.Abort时 - 你明确地中止了一个线程的执行,它是当前进入的AppDomain的问题。

无论如何,当你想做的就是卸载一些AppDomain时,你不希望你的线程被中止。