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,是的,这就是问题所在。