C# AppDomain.FirstChanceException事件订阅导致FatalExecutionEngineError

C# AppDomain.FirstChanceException事件订阅导致FatalExecutionEngineError,c#,.net,C#,.net,此类存在于其自己的DLL中。调用Ex方法显然会导致引发和处理异常: 类Foo:MarshallByRefObject { 公开无效Ex() { 对象o=null; 尝试 { 字符串s=o.ToString(); } 捕获{} } } 下面将包含Foo的DLL加载到另一个AppDomain中,创建一个Foo并调用Ex方法 使用系统; 使用系统诊断; 使用System.Runtime.ExceptionServices; 使用远程代码; 命名空间AppDomainTest { 班级计划 { 静态v

此类存在于其自己的DLL中。调用Ex方法显然会导致引发和处理异常:

类Foo:MarshallByRefObject
{
公开无效Ex()
{
对象o=null;
尝试
{
字符串s=o.ToString();
}
捕获{}
}
}
下面将包含Foo的DLL加载到另一个AppDomain中,创建一个Foo并调用Ex方法

使用系统;
使用系统诊断;
使用System.Runtime.ExceptionServices;
使用远程代码;
命名空间AppDomainTest
{
班级计划
{
静态void Main()
{
AppDomain AppDomain=AppDomain.CreateDomain(“测试”,
无效的
新AppDomainSetup
{
ApplicationBase=AppDomain.CurrentDomain.BaseDirectory
});
//appDomain.FirstChanceException+=
//(s,e)=>Debug.WriteLine(“*”+e.Exception.Message);
条形=新条形();
订阅(appDomain);
Foo Foo=(Foo)appDomain.CreateInstance(“RemoteCode”、“RemoteCode.Foo”).Unwrap();
foo.Ex();
}
}
公共类栏:MarshallByRefObject
{
公共无效订阅(AppDomain ad)
{
ad.FirstChanceException+=OnFirstChanceException;
}
private void OnFirstChanceException(对象发送方,FirstChanceExceptionEventArgs e)
{
Debug.WriteLine(“*”+e.Exception.Message);
}
}
}
结果是FatalExecutionEngineer错误:

运行时遇到致命错误。错误地址位于线程0x26f0上的0x62c6529d。错误代码为0x80131506。此错误可能是CLR或用户代码的不安全或不可验证部分中的错误。此错误的常见来源包括COM互操作或PInvoke的用户封送错误,这可能会损坏堆栈

它发生在Foo中的这一行:

string s=o.ToString();
如果我注释掉包括Bar在内的行,并取消注释前一行,那么代码工作正常,异常消息将写入调试控制台:

appDomain.FirstChanceException+=
(s,e)=>Debug.WriteLine(“*”+e.Exception.Message);
//条形=新条形();
//订阅(appDomain);
Foo Foo=(Foo)appDomain.CreateInstance(“RemoteCode”、“RemoteCode.Foo”).Unwrap();
foo.Ex();
我是在做一些愚蠢的事情,还是这是一个bug?

标签“bug”在这种情况下非常合适,不应该有来自纯托管代码的感觉。但是,您给CLR带来了非常困难的时间,在非常关键的时间将事件处理程序调用从一个AppDomain封送到另一个AppDomain。显然,它没有能力处理这一问题

你需要慎重考虑避免这种情况。只要将事件处理程序保持在同一AppDomain中,它就可以正常工作。这很好,例如:

public class Foo : MarshalByRefObject {
    public Foo() {
        AppDomain.CurrentDomain.FirstChanceException += (s, e) => {
            Debug.WriteLine("* " + e.Exception.Message);
        };
    }
    // etc...
}
我想可能不方便登录。您可以在connect.microsoft.com上提交此bug的反馈报告,标签“bug”在这种情况下非常合适,不应该有来自普通托管代码的FEEE。但是,您给CLR带来了非常困难的时间,在非常关键的时间将事件处理程序调用从一个AppDomain封送到另一个AppDomain。显然,它没有能力处理这一问题

你需要慎重考虑避免这种情况。只要将事件处理程序保持在同一AppDomain中,它就可以正常工作。这很好,例如:

public class Foo : MarshalByRefObject {
    public Foo() {
        AppDomain.CurrentDomain.FirstChanceException += (s, e) => {
            Debug.WriteLine("* " + e.Exception.Message);
        };
    }
    // etc...
}

我想可能不方便登录。您可以在connect.microsoft.com上提交此错误的反馈报告

谢谢。我向Microsoft提交了一个bug(连接时为804982),谢谢。我向Microsoft提交了一个bug(Connect上的804982)