C# 匿名方法在访问局部变量时引发运行时异常

C# 匿名方法在访问局部变量时引发运行时异常,c#,anonymous-methods,C#,Anonymous Methods,为什么下面的代码抛出以下错误 private static void CreateNewAppDomain() { var cd = AppDomain.CreateDomain("CustomDomain1"); cd.DomainUnload += (sender, args) => Console.WriteLine("Domain 0 unloading, sender{0}, args{1} domain {2}", sender, args,cd); }

为什么下面的代码抛出以下错误

private static void CreateNewAppDomain() {
   var cd = AppDomain.CreateDomain("CustomDomain1");
   cd.DomainUnload += (sender, args) => Console.WriteLine("Domain 0 unloading,       sender{0}, args{1} domain {2}", sender, args,cd);
}



System.Runtime.Serialization.SerializationException was unhandled  Message=Type 'CoreConstructs.AppDomainPlay+<>c__DisplayClass3' in assembly 'CoreConstructs, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2642f93804f4bbd8' is not marked as serializable.  Source=mscorlib
  StackTrace:
       at System.AppDomain.add_ProcessExit(EventHandler value)
       at CoreConstructs.AppDomainPlay.CreateNewAppDomain() in C:\work\sampleCode\exploreCsharp\exploreCSharp\ParameterPassing\AppDomainPlay.cs:line 31
       at CoreConstructs.AppDomainPlay.ExploreAppDomain() in C:\work\sampleCode\exploreCsharp\exploreCSharp\ParameterPassing\AppDomainPlay.cs:line 19
       at CoreConstructs.Program.Main(String[] args) in C:\work\sampleCode\exploreCsharp\exploreCSharp\ParameterPassing\Program.cs:line 14
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
private static void CreateNewAppDomain(){
var cd=AppDomain.CreateDomain(“CustomDomain1”);
cd.DomainUnload+=(发送方,args)=>Console.WriteLine(“域0卸载,发送方{0},args{1}域{2}”,发送方,args,cd);
}
System.Runtime.Serialization.SerializationException未处理消息=类型“CoreConstructs.AppDomainPlay+c__DisplayClass3”在程序集中“CoreConstructs,版本=1.0.0.0,区域性=中性,PublicKeyToken=2642F3804F4BD8”未标记为可序列化。Source=mscorlib
堆栈跟踪:
在System.AppDomain.add_ProcessExit(EventHandler值)处
在C:\work\sampleCode\ExploreCharp\ExploreCharp\ParameterPassing\AppDomainPlay.cs中的CoreConstructs.AppDomainPlay.CreateNewAppDomain()处:第31行
在C:\work\sampleCode\exploreCsharp\exploreCsharp\ParameterPassing\AppDomainPlay.cs中的CoreConstructs.AppDomainPlay.ExploreAppDomain()处:第19行
在C:\work\sampleCode\exploreCsharp\exploreCsharp\ParameterPassing\Program.cs中的CoreConstructs.Program.Main(字符串[]args)处:第14行
位于System.AppDomain.\u nExecuteAssembly(RuntimeAssembly程序集,字符串[]args)
位于System.AppDomain.ExecuteAssembly(字符串汇编文件、证据汇编安全性、字符串[]args)
在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()上
位于System.Threading.ThreadHelper.ThreadStart\u上下文(对象状态)
在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,对象状态,布尔ignoreSyncCtx)
在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,对象状态)
位于System.Threading.ThreadHelper.ThreadStart()处
内部异常:

这是因为您试图在
DomainUnload
方法内部使用
cd
变量,而此变量在外部范围内定义。

这是因为您试图在
DomainUnload
方法内部使用
cd
变量,而此变量在外部范围内定义。

编译器生成一个不可见的助手类来实现lambda。您可以在异常消息中看到它的名称,
c\u DisplayClass3
。由于lambda在添加的appdomain中运行,因此需要将此帮助器类的实例从主域序列化到该appdomain

这无法工作,这些帮助器类没有[Serializable]属性。这里不能使用lambda,只需在静态助手函数上使用常规事件分配语法即可。像这样:

       cd.DomainUnload += NewAppDomain_DomainUnload;
    ...

    private static void NewAppDomain_DomainUnload(object sender, EventArgs e) {
        Console.WriteLine("AppDomain {0} unloading", AppDomain.CurrentDomain);
    }
C#编译器生成一个不可见的助手类来实现lambda。您可以在异常消息中看到它的名称,
c\u DisplayClass3
。由于lambda在添加的appdomain中运行,因此需要将此帮助器类的实例从主域序列化到该appdomain

这无法工作,这些帮助器类没有[Serializable]属性。这里不能使用lambda,只需在静态助手函数上使用常规事件分配语法即可。像这样:

       cd.DomainUnload += NewAppDomain_DomainUnload;
    ...

    private static void NewAppDomain_DomainUnload(object sender, EventArgs e) {
        Console.WriteLine("AppDomain {0} unloading", AppDomain.CurrentDomain);
    }

通常情况下,这是可以的,对吗?这里的问题实际上是
cd
持有的对象与OnUnload处理程序执行的代码位于不同的AppDomain中吗?这就解释了
SerializationException
@Eric,是的,这就是这里的问题。正常情况下,这没问题,对吧?这里的问题实际上是
cd
持有的对象与OnUnload处理程序执行的代码位于不同的AppDomain中吗?这就解释了
SerializationException
@Eric,是的,这就是问题所在。