c# - 如何跨 AppDomain 将引用作为方法参数传递?

标签 c# .net remoting appdomain marshalbyrefobject

我一直在努力让下面的代码工作(一切都在同一个程序集中定义):

namespace SomeApp{

public class A : MarshalByRefObject
{
   public byte[] GetSomeData() { // }
}

public class B : MarshalByRefObject
{
   private A remoteObj;

   public void SetA(A remoteObj)
   {
      this.remoteObj = remoteObj;
   }
}

public class C
{
   A someA = new A();
   public void Init()
   {
       AppDomain domain = AppDomain.CreateDomain("ChildDomain");
       string currentAssemblyPath = Assembly.GetExecutingAssembly().Location;
       B remoteB = domain.domain.CreateInstanceFromAndUnwrap(currentAssemblyPath,"SomeApp.B") as B;
       remoteB.SetA(someA); // this throws an ArgumentException "Object type cannot be converted to target type."
   }
}

}

我想做的是将在第一个 AppDomain 中创建的“A”实例的引用传递给子域,并让子域在第一个域上执行一个方法。在“B”代码的某个点上,我将调用“remoteObj.GetSomeData()”。必须这样做,因为必须在第一个应用程序域上“计算”来自“GetSomeData”方法的“byte[]”。 我应该怎么做才能避免异常,或者我该怎么做才能达到相同的结果?

最佳答案

真正的根本原因是您的 dll 是从两个不同应用程序域中的不同位置加载的。这导致 .NET 认为它们是不同的程序集,这当然意味着类型不同(即使它们具有相同的类名、命名空间等)。

Jeff 的测试在通过单元测试框架运行时失败的原因是因为单元测试框架通常会创建 AppDomains,并将 ShadowCopy 设置为“true”。但是您手动创建的 AppDomain 将默认为 ShadowCopy="false"。这将导致从不同位置加载 dll,从而导致“对象类型无法转换为目标类型”。错误。

更新:经过进一步测试,似乎确实归结为两个 AppDomain 之间的 ApplicationBase 不同。如果它们匹配,则上述情况有效。如果它们不同,则不会(即使我已经确认使用 windbg 从同一目录将 dll 加载到两个 AppDomains 中)另外,如果我在我的两个 AppDomains 中打开 ShadowCopy="true",那么它会失败带有不同的消息:“System.InvalidCastException:对象必须实现 IConvertible”。

更新 2:进一步阅读让我相信它与 Load Contexts 有关.当您使用其中一种“From”方法(Assembly.LoadFrom 或 appDomain.CreateInstanceFromAndUnwrap)时,如果在其中一个正常加载路径(ApplicationBase 或其中一个探测路径)中找到该程序集,那么它是否加载到 Default加载上下文。如果在那里找不到该程序集,则会将其加载到 Load-From 上下文中。因此,当两个 AppDomain 都具有匹配的 ApplicationBase 时,即使我们使用“From”方法,它们也会加载到各自 AppDomain 的默认加载上下文中。但是当 ApplicationBase 不同时,一个 AppDomain 将在其默认加载上下文中包含程序集,而另一个在其加载源上下文中包含程序集。

关于c# - 如何跨 AppDomain 将引用作为方法参数传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2932370/

相关文章:

.net - 我的对象总是 "be there"吗?

.net - 需要那些不在表中的

javascript - 多个 javascript 远程处理函数完成时的函数/事件

HTTP代理服务器中的Delphi DataSap

c# - 在 WebAPI OData 请求中包含相关实体

c# - pig 拉丁翻译崩溃C#

c# - 将列表传递给 asp.net 下拉列表?

c# - 亚马逊 S3 : How to get a list of folders in the bucket?

.net - 从 .NET 应用程序中删除元数据?

.net - MarshalByRefObject 很特别吗?