跨应用程序域边界传递 IEnumerable

发布于 2024-08-17 11:19:55 字数 188 浏览 8 评论 0原文

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

我问这个问题是因为根据我目前对 IEnumerable 实现的理解,在枚举集合之前不会使用枚举器。当您跨越应用程序域边界时,特别是涉及多个进程时,这是否会导致多次跨越边界,每返回一项就一次?如果是这种情况,那么在可能的情况下(例如在数组中)返回整个集合在性能方面会更好,不是吗?

Is it generally a bad idea to pass an IEnumerable across appdomain boundaries?

I ask because with my current understanding of IEnumerable implementations, the enumerator isn't going to be used until the collection is, well, enumerated. When you are crossing appdomain boundaries, particularly involving multiple processes, would this not result in multiple trips across the boundary, one for every item returned? If that is the case, then returning the collection in its entirety, when possible, such as in an array, would be preferable in terms of performance, would it not?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

春庭雪 2024-08-24 11:19:55

首先,它取决于要枚举的对象是如何的:是否继承自MarshalByRef,或者是否可序列化。在第二种情况下,副本被传递到另一个应用程序域,这类似于数组方法。另一方面,如果它继承自 MarshalByRef,则它很大程度上取决于枚举器如何访问所有者实例。

因此,总的来说,我想说,如果您确实知道会发生什么,则应该只在应用程序域中传递 IEnumerable 。否则,您可能会得到意想不到的结果或性能不佳。

First, it depends how the object to be enumerated is: whether is inherits from MarshalByRef or if it is serializable. In the second case, a copy is passed to the other appdomain, which then resembles the array approach. On the other hand, if it inherits from MarshalByRef, it pretty much depends how the enumerator is accessing the owner instance.

So in general, I'd say that you should only pass IEnumerables accross appdomains if you do know what to expect. Otherwise, you may get unexpected results or bad performance.

情丝乱 2024-08-24 11:19:55

实际上,假设 MarshalByRefObject,则每个项目为 2 趟(加一);一个到 MoveNext(),一个到 Current(对于每个返回 trueMoveNext())。再加上 GetEnumerator() 调用,可能还有 Dispose()。因此,对于 MarshalByRefObject,不:不要这样做;使用数组。

但是,如果它不是 MarshalByRefObject,那就更有趣了。例如,ADO.NET 数据服务在 LINQ API 上公开数据(IQueryable: IEnumerable),但这通过在需要时构建特定查询、执行一次往返以及迭代回到客户端。

当然,您可能不应该在任何实际距离上使用远程(更喜欢 WCF 等),因此也许第一个场景并不是一个问题 - 您不会的延迟太多。另外,您将在实体上遇到相同的延迟问题(如果MarshalByRefObject)或序列化成本(如果没有)。

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

Actually, assuming MarshalByRefObject, it is 2 trips per item (plus one); one to MoveNext(), and one to Current (for every MoveNext() that returns true). Plus a GetEnumerator() call, and probably a Dispose(). So for a MarshalByRefObject, no: don't do this; use an array.

However, if it isn't MarshalByRefObject it is more interesting. For example, ADO.NET Data Services exposes data on a LINQ API (IQueryable<T> : IEnumerable<T>), but this works by building a specific query when needed, doing one round trip, and iterating back at the client.

Of course, you probably shouldn't be using remoting over any real distance (prefer WCF etc), so maybe the first scenario isn't a huge problem - you won't have much latency. Plus you'll either have the same latency issues on the entities (if MarshalByRefObject) or the serialization costs (if not).

Personally, on the very few occasions I use remoting (usually just to allow dll unloading), I have a MarshalByRefObject to represent some kind of service, and serializable entity objects. Perhaps rather predictably for me, I use protobuf-net to minimise the serialization cost.

彼岸花ソ最美的依靠 2024-08-24 11:19:55

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

Yeah, it is a bad idea. An enumerator almost always keeps a reference to the collection it is enumerating. Assuming both are serializable, you'll serialize the entire collection as well when you cross the boundary. No round-trips though.

音盲 2024-08-24 11:19:55

是的。即使跨线程传递它也是不安全的。你最好将其转换为数组来传递。

yeah. it's not safe even to pass it across threads. you'd better convert it to array to pass.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文