Передача IEnumerable через границы домена приложения - PullRequest
4 голосов
/ 09 января 2010

Является ли вообще плохой идеей передавать IEnumerable через границы домена приложения?

Я спрашиваю, потому что с моим текущим пониманием реализаций IEnumerable перечислитель не будет использоваться до тех пор, пока коллекция не будет нумерована. Когда вы пересекаете границы домена приложения, особенно с участием нескольких процессов, не приведет ли это к нескольким поездкам через границу, по одному на каждый возвращенный элемент? Если это так, то возврат коллекции во всей ее полноте, когда это возможно, например, в массиве, будет предпочтительнее с точки зрения производительности, не так ли?

Ответы [ 4 ]

3 голосов
/ 09 января 2010

Во-первых, это зависит от того, как будет перечисляться объект: наследуется ли он от MarshalByRef или является ли он сериализуемым. Во втором случае копия передается другому домену приложения, который затем напоминает подход массива. С другой стороны, если он наследуется от MarshalByRef, это в значительной степени зависит от того, как перечислитель обращается к экземпляру владельца.

В общем, я бы сказал, что вы должны передавать IEnumerable через домены только в том случае, если знаете, чего ожидать. В противном случае вы можете получить неожиданные результаты или плохую производительность.

2 голосов
/ 09 января 2010

На самом деле, при условии MarshalByRefObject, это 2 поездок за единицу (плюс один); один к MoveNext() и один к Current (для каждого MoveNext(), который возвращает true). Плюс GetEnumerator() звонок, и, вероятно, Dispose(). Так что для MarshalByRefObject нет: не делай этого; использовать массив.

Однако, если это не MarshalByRefObject, это более интересно. Например, ADO.NET Data Services предоставляет данные в API LINQ (IQueryable<T> : IEnumerable<T>), но это работает путем создания определенного запроса при необходимости, выполнения одного цикла и повторения итерации на клиенте.

Конечно, вам, вероятно, не следует использовать удаленное взаимодействие на любом реальном расстоянии (предпочтительнее WCF и т. Д.), Поэтому, возможно, первый сценарий не является огромной проблемой - вы выиграли много задержки. Кроме того, у вас возникнут те же проблемы с задержкой на объектах (если MarshalByRefObject) или затраты на сериализацию (если нет).

Лично, в очень немногих случаях, когда я использую удаленное взаимодействие (обычно просто для того, чтобы разрешить выгрузку dll), у меня есть MarshalByRefObject для представления некоторого вида сервиса и сериализуемых объектов сущности. Возможно, для меня это вполне предсказуемо, я использую protobuf-net, чтобы минимизировать стоимость сериализации.

1 голос
/ 09 января 2010

Да, это плохая идея. Перечислитель почти всегда сохраняет ссылку на коллекцию, которую он перечисляет. Предполагая, что оба сериализуются, вы также сериализуете всю коллекцию, когда пересекаете границу. Никаких поездок туда и обратно.

0 голосов
/ 09 января 2010

да.это даже небезопасно передавать через потоки.лучше передать его в массив для передачи.

...