根据 Microsoft 文档,在线程池或使用 System.Threading.Thread 类创建的线程发生未处理异常时,应用程序的默认 AppDomain 应触发 AppDomain.UnhandledException 事件。这是 MSDN link 在第二个注意事项后解释的内容。
但是,我无法重现此行为。据我测试应用程序所示,它从未在默认 AppDomain 或用于创建线程的 AppDomain 上触发 UnhandledException。文档有误还是我的测试代码有问题?
但是,我无法重现此行为。据我测试应用程序所示,它从未在默认 AppDomain 或用于创建线程的 AppDomain 上触发 UnhandledException。文档有误还是我的测试代码有问题?
using System;
using System.Runtime.ExceptionServices;
using System.Reflection;
public class Program
{
static void Main()
{
Program.HookAppDomainExceptions();
Test t = CreateTestInsideAppDomain("Nested1");
t.SetupNested1();
Console.ReadLine();
}
public static Test CreateTestInsideAppDomain(string appDomainName)
{
AppDomain nested1 = AppDomain.CreateDomain(appDomainName);
string executingName = Assembly.GetExecutingAssembly().FullName;
return (Test)nested1.CreateInstanceAndUnwrap(executingName, "Test");
}
public static void HookAppDomainExceptions()
{
AppDomain.CurrentDomain.FirstChanceException +=
new EventHandler<FirstChanceExceptionEventArgs>(FirstChanceException);
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}
public static void FirstChanceException(object sender, FirstChanceExceptionEventArgs e)
{
Console.WriteLine("Domain:{0} FirstChanceException Handler",
AppDomain.CurrentDomain.FriendlyName);
}
public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine("Domain:{0} UnhandledException Handler",
AppDomain.CurrentDomain.FriendlyName);
}
}
public class Test : MarshalByRefObject
{
private delegate void Nothing();
public void SetupNested1()
{
var start = new Nothing(Nested1ThreadStart);
start.BeginInvoke(null, null);
}
static void Nested1ThreadStart()
{
Program.HookAppDomainExceptions();
Test t = Program.CreateTestInsideAppDomain("Nested2");
t.SetupNested2();
}
public void SetupNested2()
{
Program.HookAppDomainExceptions();
Test t = Program.CreateTestInsideAppDomain("Nested3");
t.ThrowException();
}
public void ThrowException()
{
Program.HookAppDomainExceptions();
throw new ApplicationException("Raise Exception");
}
}
start.BeginInvoke(iar => start.EndInvoke(iar), null)
,因为你的用法会使方法调用同步。不过,回答非常好! - Jonathan Dickinsonstart
的线程上调用EndInvoke()
,这意味着它会在Nested1
(和主域)上引发UnhandledException
。 - svick