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() 如何中止线程?的主要内容,如果未能解决你的问题,请参考以下文章