跨应用程序域边界传递IEnumerable

时间:2010-01-09 16:28:12

标签: c# .net performance remoting appdomain

跨应用程序域边界传递IEnumerable通常是个坏主意吗?

我问,因为我目前对IEnumerable实现的理解,直到集合被枚举后才会使用枚举器。当您跨越appdomain边界,特别是涉及多个进程时,这不会导致跨越边界的多次跳转,每个项目返回一次吗?如果是这种情况,那么在可能的情况下(例如在数组中)完整地返回集合在性能方面会更好,不是吗?

4 个答案:

答案 0 :(得分:3)

首先,它取决于枚举对象的方式:是继承自MarshalByRef还是可序列化。在第二种情况下,副本将传递给另一个appdomain,然后类似于数组方法。另一方面,如果它继承自MarshalByRef,那么它几乎取决于枚举器如何访问所有者实例。

所以一般来说,如果您确实知道会发生什么,我应该说只应通过IEnumerable个应用程序域。否则,您可能会收到意外结果或性能不佳。

答案 1 :(得分:2)

实际上,假设MarshalByRefObject,每件商品的行程 2 (加一);一个到MoveNext(),一个到Current(每个MoveNext()返回true)。加上GetEnumerator()来电,可能是Dispose()。所以对于MarshalByRefObject,不,不要这样做;使用数组。

但是,如果不是 MarshalByRefObject,那就更有趣了。例如,ADO.NET数据服务公开LINQ API(IQueryable<T> : IEnumerable<T>)上的数据,但这可以通过在需要时构建特定查询,进行一次往返并在客户端迭代来实现。

当然,您可能不应该在任何真实距离上使用远程(更喜欢WCF等),因此第一种情况可能不是巨大的问题 - 你不会有多少延迟。此外,您将在实体上遇到相同的延迟问题(如果MarshalByRefObject)或序列化成本(如果没有)。

就个人而言,在极少数场合我使用远程处理(通常只是为了允许dll卸载),我有一个MarshalByRefObject代表某种服务和可序列化的实体对象。也许对我来说可能是可以预见的,我使用protobuf-net来最小化序列化成本。

答案 2 :(得分:1)

是的,这是一个坏主意。枚举器几乎总是保持对它所枚举的集合的引用。假设两者都是可序列化的,那么当您越过边界时,您也会序列化整个集合。不过往返。

答案 3 :(得分:0)

耶。即使将它传递给线程也不安全。你最好把它转换成数组来传递。