【问题标题】:Are parameters of a method call of a proxied (marshallbyref) object serialized?代理(marshallbyref)对象的方法调用的参数是否序列化?
【发布时间】:2012-02-11 19:16:19
【问题描述】:

我正在努力解决这个问题,以做出正确的设计决策。

假设我创建了一个新的 appdomain B,在其中创建一个对象 O 的实例,然后将该对象的引用传递回 appdomain A,以便 A 可以进行如下调用:

O.SomeMethod(parameter)

SomeMethod 中的代码将在 appdomain B 中运行,这正是我所期望的。 我想知道参数和返回值会发生什么变化它们是使用 binaryformatter 进行序列化并按值传递,还是对该数据的引用只是在 appdomain 之间传递?

我希望是后者,这意味着您可以让 O.SomeMethod() 返回大量数据而不会造成序列化损失。

谢谢!

【问题讨论】:

  • 是什么让您认为 BinaryFormatter 没有序列化惩罚?序列化就是它所做的,二进制类型。除非参数类型派生自 MRBO,否则使用。
  • 我认为你误读了我写的内容。在仅传递引用的情况下假定“没有序列化惩罚”,因此不使用二进制格式化程序(或下面使用的任何内容)。
  • 假设返回值是一个 MBRO 对象,其中包含一个 10 兆字节的数组。那个对象是序列化的吗?如果不是,并且主机尝试读取该数组中的字节,它是否只是从所有者 appdomain 放入的实际内存位置获取它?
  • 数组不是从 MBRO 派生的,因此无论何时访问它都会被整体序列化。不顾外物。必然如此,否则读取每个元素会非常昂贵。
  • 嗯好的。所以没有办法避免原始数据的应用程序域间通信中的序列化?希望通过使用 appdomains 而不是进程,我可以将尽可能多的组件链接在一起,并传递大量数据而不会产生潜在的序列化成本。关于那个话题,.NET 在幕后使用 binaryformatter 吗?这意味着 appdomains 之间的远程处理将比使用 sockets + protobuf.net 之类的进程间通信慢(在序列化时明显快 10 倍)!?

标签: .net serialization marshalling remoting


【解决方案1】:

传递给函数的参数需要在调用方法之前通过appdomain边界。返回值也需要越过边界(反方向)。

任何时候一个对象需要通过它的边界:

  1. 如果继承自MarshalByRefObject,则按引用编组;或
  2. 在一侧序列化,通过边界传输,然后反序列化。如果它不继承自 MBRO,就会发生这种情况。

回答您的问题,是的,参数先被序列化然后反序列化,除非它们继承自 MBRO

【讨论】:

  • 所以如果你继续沿着 MBRO 链往下走,你最终会得到一堆原语,它们大概是按值传递的?还是在共享内存中?
  • 不,如果你传递一个MBRO,它的字段不会被序列化。如果你在它上面执行了一些方法,它返回的不是MBRO,那就是序列化的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-21
  • 2011-05-07
  • 1970-01-01
  • 2017-10-27
  • 2013-02-16
  • 2013-01-23
相关资源
最近更新 更多