【问题标题】:AppDomain.CurrentDomain.Evidence throws SerializationExceptionAppDomain.CurrentDomain.Evidence 抛出 SerializationException
【发布时间】:2015-01-23 18:39:16
【问题描述】:

我在使用带有 VS 2013 的 ReSharper (8.2.2) 运行我的测试用例时遇到了一个奇怪的错误。

一个演示问题的简化测试用例只包含两行代码:

CallContext.LogicalSetData("mydata", new ActivityStack());
var evidence = AppDomain.CurrentDomain.Evidence;

其中 ActivityStack 是可序列化的自定义类型。当通过 ReSharper 运行测试用例时,第二行会抛出异常:

System.Runtime.Serialization.SerializationException was unhandled by user code
  HResult=-2146233076
  Message=Type is not resolved for member 'CSG.Framework.Operations.ActivityStack,CSG.Framework, Version=15.2.0.0, Culture=neutral, PublicKeyToken=e7ab1d859f54b223'.
  Source=mscorlib
  StackTrace:
       at System.AppDomain.get_Evidence()
       at System.AppDomain.get_Evidence()
       at CSG.Framework.Utilities.AppDomainLauncher`1..ctor(String appDomainName) in d:\Work\Git\Framework\Src\Library\Framework\Utilities\AppDomainLauncher.cs:line 40
       at CSG.Framework.UnitTest.AppDomainLauncherTests.LaunchClassFromCallingAssembly() in d:\Work\Git\Framework\Src\Library\Framework.UnitTest\Utilities\AppDomainLauncherTests.cs:line 52
  InnerException: 

尽管当前 AppDomain 似乎在 BaseDirectory 上有正确的路径,可以在其中找到包含该类型的程序集,但 CLR 似乎仍在使用 ReSharper bin 路径根据 Fusion 日志探测程序集。如果我将程序集复制到 ReSharper bin 文件夹,问题就会消失,但我认为这不是正确的解决方案。我尝试订阅当前 AppDomain 上的 AssemblyResolve 事件,但未调用处理程序。

融合日志:

*** Assembly Binder Log Entry  (1/23/2015 @ 12:28:54 PM) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:     C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  C:\Program Files (x86)\JetBrains\ReSharper\v8.2.Qiwabic\Bin\JetBrains.ReSharper.TaskRunner.CLR45.x64.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = CSG.Framework, Version=15.2.0.0, Culture=neutral, PublicKeyToken=e7ab1d859f54b223 (Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = JetBrains.ReSharper.TaskRunner.CLR45.x64.exe Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Program Files (x86)\JetBrains\ReSharper\v8.2.Qiwabic\Bin\JetBrains.ReSharper.TaskRunner.CLR45.x64.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: CSG.Framework, Version=15.2.0.0, Culture=neutral, PublicKeyToken=e7ab1d859f54b223
LOG: GAC Lookup was unsuccessful.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/CSG.Framework.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/CSG.Framework/CSG.Framework.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/CSG.Framework.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/CSG.Framework/CSG.Framework.EXE.
LOG: All probing URLs attempted and failed.

【问题讨论】:

  • 不确定是否有“正确”的解决方案,除了在运行测试之前将程序集加载到 appdomain 中(简单的typeof 就可以了)。
  • 自定义类型(ActivityStack)与正在执行的代码在同一个程序集中(与测试用例在同一个文件中定义),所以我相信它应该已经加载了。跨度>
  • 是否有内部异常?也许这里发生了其他事情......
  • 内部异常为null。
  • 这很奇怪,因为您通常不会在异常详细信息中看到“InnerException:”,除非它不为空。

标签: c# .net


【解决方案1】:

此链接 (https://msdn.microsoft.com/en-us/library/dn458353(v=vs.110).aspx) 解释了根本原因。

涉及两个应用程序域:默认应用程序域(ReSharper 运行程序)和当前应用程序域(测试用例)。当 AppDomain.Evidence 在当前应用域执行时:

  • 它会寻找当前应用程序域的证据。
  • 它尝试计算当前应用程序域的证据 基于当前域。
  • 获取当前域证据的调用会触发 从当前应用域到默认的跨应用域调用 应用域。
  • 作为 .NET Framework 中跨应用域合同的一部分, 逻辑调用上下文的内容也必须被编组 应用域边界。

由于逻辑调用上下文中的类型(ActivityStack)在默认应用域中无法解析,因此抛出异常。

【讨论】:

    【解决方案2】:

    我有类似的问题。如果您将顺序更改为:

    var evidence = AppDomain.CurrentDomain.Evidence;
    CallContext.LogicalSetData("mydata", new ActivityStack());
    

    它会起作用的。在我的项目中,我创建了一个 Mocked Principal 并在设置步骤中分配给 Thread.CurrentPrincipal。当我在 AppDomain.Evidence 调用之后移动该分配时(这是 NHibernate 的自动调用)。有用 :) 希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-22
      • 2011-01-08
      • 2017-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多