gpt4 book ai didi

c# - 在另一个线程中抛出异常时不调用 UnhandledException

转载 作者:太空狗 更新时间:2023-10-29 18:27:55 28 4
gpt4 key购买 nike

根据 Microsoft 文档,当线程(来自线程池或使用 System.Threading.Thread 类创建)发生未处理的异常时,应为应用程序的默认 AppDomain 触发 AppDomain.UnhandledException 事件。这是 MSDN link在第二个注释部分之后解释了它。

但我无法重现此行为,据我从我的测试应用程序中得知,它永远不会在默认 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");
}
}

最佳答案

在您的代码中,UnhandledException 不会在任何 AppDomain 上触发,因为如果您使用 BeginInvoke() 调用委托(delegate),任何异常在其执行期间抛出被处理,然后在您调用 EndInvoke() 时重新抛出,而您没有这样做。

如果您调用 EndInvoke():

start.EndInvoke(start.BeginInvoke(null, null));

或者同步执行委托(delegate):

start();

您会得到类似的结果:引发了主域的 UnhandledException

相反,如果您按照文档中的说明操作并使用 Thread 类启动一个新线程:

new Thread(Nested1ThreadStart).Start();
Nested1 和主应用程序域的

UnhandledException 被引发。

因此,回答您的问题:文档是正确的。你的代码是错误的。当您使用 BeginInvoke() 异步调用委托(delegate)时,您应该始终稍后调用 EndInvoke()

关于c# - 在另一个线程中抛出异常时不调用 UnhandledException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7378816/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com