TypeAccessException:尝试按方法...访问类型...失败

时间:2011-06-15 10:33:31

标签: .net

完整的例外情况包括:

System.TypeAccessException occurred
  Message=Attempt by method 'DynamicClass.(System.Text.StringBuilder, System.Object, Int32)' to access type 'System.Collections.Generic.IEnumerable`1<System.Collections.Generic.KeyValuePair`2<System.Object,NetworkCatcher.Entities.Server.CalculatedFCStateManager+Descriptor>>' failed.
  Source=Anonymously Hosted DynamicMethods Assembly
  TypeName=""
  StackTrace:
       at (StringBuilder , Object , Int32 )
  InnerException: 

方法名称DynamicClass.(System.Text.StringBuilder, System.Object, Int32)对应于此动态生成的方法:

private delegate StringBuilder AppendToStringBuilderDelegate(StringBuilder sb, object obj, int maxItemsToDisplay);

private static AppendToStringBuilderDelegate EmitDelegate(Type type, MethodInfo methodInfo)
{
  var dynamicMethod = new DynamicMethod(string.Empty, typeof(StringBuilder), TypeArray<StringBuilder, object, int>.Value);
  var parameters = methodInfo.GetParameters();

  var il = dynamicMethod.GetILGenerator();
  il.Emit(OpCodes.Ldarg_0);
  il.Emit(OpCodes.Ldarg_1);
  il.Emit(OpCodes.Unbox_Any, parameters[1].ParameterType);
  il.Emit(OpCodes.Ldarg_2);
  il.EmitCall(OpCodes.Call, methodInfo, null);
  il.Emit(OpCodes.Ret);
  return s_methodCache[type] = (AppendToStringBuilderDelegate)dynamicMethod.CreateDelegate(typeof(AppendToStringBuilderDelegate));
}

堆栈跟踪是:

[Lightweight Function]  
Shunra.Common.dll!Shunra.Common.DebugUtils.AppendObject<System.Collections.Generic.IDictionary<object,NetworkCatcher.Entities.Server.CalculatedFCStateManager.Descriptor>>(System.Text.StringBuilder sb, System.Collections.Generic.IDictionary<object,NetworkCatcher.Entities.Server.CalculatedFCStateManager.Descriptor> obj, int maxItemsToDisplay) Line 261 + 0x14 bytes    C#
Shunra.Common.dll!Shunra.Common.DebugUtils.ToString<System.Collections.Generic.IDictionary<object,NetworkCatcher.Entities.Server.CalculatedFCStateManager.Descriptor>>(System.Collections.Generic.IDictionary<object,NetworkCatcher.Entities.Server.CalculatedFCStateManager.Descriptor> obj, int maxItemsToDisplay) Line 435 + 0x4d bytes  C#
NC.Entities.Server.dll!NetworkCatcher.Entities.Server.CalculatedFCStateManager.Populate() Line 98 + 0x2c bytes  C#
NC.Entities.Server.dll!NetworkCatcher.Entities.Server.RunManager.Initialize() Line 500 + 0x1c bytes C#
NC.Entities.Server.dll!NetworkCatcher.Entities.Server.EntryPoint.OnStart() Line 63 + 0x5 bytes  C#
Shunra.Infra.dll!Shunra.Infra.EntryPoint.Start() Line 37 + 0xb bytes    C#
Shunra.Common.dll!Shunra.Common.Wcf.ShunraServiceHost.OnOpening() Line 47 + 0x11 bytes  C#
System.ServiceModel.dll!System.ServiceModel.Channels.CommunicationObject.Open(System.TimeSpan timeout) + 0x113 bytes    
System.ServiceModel.dll!System.ServiceModel.Channels.CommunicationObject.Open() + 0x25 bytes    
NC.Server.Host.exe!NetworkCatcher.Server.Host.NCServerInstance.StartHosts() + 0xef bytes    
Shunra.Common.dll!Shunra.Common.Wcf.ShunraServerInstance<NetworkCatcher.Server.Host.NCServerInstance,NetworkCatcher.Server.Host.ServerHost>.Run() Line 357 + 0xb bytes  C#
NC.Server.Host.exe!NetworkCatcher.Server.Host.Program.Main(string[] args) + 0x84 bytes  

最后,两个程序集--Sunra.Common.dll和NC.Entities.Server.dll属于相同的代码库。 NC.Entities.Server.dll从位于根文件夹正下方的私人bin文件夹加载,其中存在Shunra.Common.dll。

一切正常,直到我决定在另一个帐户下运行代码。因此,我创建了一个新帐户,使其成为管理员并在此帐户下打开了一个提升的控制台窗口。 该帐户可以访问所有文件。不过,当我运行应用程序时,我收到此错误,我完全迷失了它。

3 个答案:

答案 0 :(得分:12)

我最近遇到了类似的问题,结果发现我打电话的类型(即MethodInfo.DeclaringType)是内部的。将其设置为public后,类型访问成功。

答案 1 :(得分:0)

您可以通过运行fuslogvw(Fusion Log Viewer)了解更多信息。如果您不熟悉它,它可以让您记录所有绑定和尝试绑定到.NET程序集 - 它将告诉您查找程序集的所有路径,并可能为您提供更多绑定失败的原因。如果你熟悉它,你可以忽略我要说的其余部分!

如果不是绑定失败,至少你已经消除了一种可能性。

要从Visual Studio cmmand提示符运行查看器fuslogvw,并将“禁用日志”中的设置更改为“将日志绑定失败到磁盘”或“将所有绑定到磁盘”(根据首选项)。再次运行代码并单击“刷新”。双击条目以查看详细信息。

确保在完成后禁用日志 - fuslogvw正在监视所有进程中的绑定,如果让它保持运行计算机,则1)慢,2)填写日志。

答案 2 :(得分:0)

我有一个类似的异常,异常的症状围绕一个委托类型并在我的Moq'ed类上使用CallBase = true。

为我解决这个问题的方法是让代表在范围内公开,以便通过Moq看到它。我们最初将委托作为受保护的范围,我收到了这个例外,因此似乎需要公共范围。

对于原始问题,我认为您需要更改

a

private delegate StringBuilder AppendToStringBuilderDelegate(StringBuilder sb, object obj, int maxItemsToDisplay);