此类存在于它自己的 DLL 中。调用 Ex 方法很明显会导致抛出和处理异常:
class Foo : MarshalByRefObject
{
public void Ex()
{
object o = null;
try
{
string s = o.ToString();
}
catch { }
}
}
下面将包含 Foo 的 DLL 加载到另一个 AppDomain 中,创建一个 Foo 并调用 Ex 方法。
using System;
using System.Diagnostics;
using System.Runtime.ExceptionServices;
using RemoteCode;
namespace AppDomainTraceTest
{
class Program
{
static void Main()
{
AppDomain appDomain = AppDomain.CreateDomain("TEST",
null,
new AppDomainSetup
{
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
});
// appDomain.FirstChanceException +=
// (s, e) => Debug.WriteLine("* " + e.Exception.Message);
Bar bar = new Bar();
bar.Subscribe(appDomain);
Foo foo = (Foo)appDomain.CreateInstance("RemoteCode", "RemoteCode.Foo").Unwrap();
foo.Ex();
}
}
public class Bar : MarshalByRefObject
{
public void Subscribe(AppDomain ad)
{
ad.FirstChanceException += OnFirstChanceException;
}
private void OnFirstChanceException(object sender, FirstChanceExceptionEventArgs e)
{
Debug.WriteLine("* " + e.Exception.Message);
}
}
}
结果是一个 FatalExecutionEngineError:
运行时遇到致命错误。错误地址位于线程 0x26f0 上的 0x62c6529d。错误代码为 0x80131506。此错误可能是 CLR 中的错误或用户代码的不安全或不可验证部分中的错误。此错误的常见来源包括 COM 互操作或 PInvoke 的用户封送错误,这可能会损坏堆栈。
它发生在 Foo 的这一行:
string s = o.ToString();
如果我注释掉包括 Bar 在内的行,并取消注释前一行,则代码工作正常,异常消息将写入调试控制台:
appDomain.FirstChanceException +=
(s, e) => Debug.WriteLine("* " + e.Exception.Message);
//Bar bar = new Bar();
//bar.Subscribe(appDomain);
Foo foo = (Foo)appDomain.CreateInstance("RemoteCode", "RemoteCode.Foo").Unwrap();
foo.Ex();
我是在做一些愚蠢的事情,还是这是一个错误?