WCF net.pipe прерывается при получении ответа - PullRequest
0 голосов
/ 10 ноября 2010

Это было решено


Это контракт, который я не могу получить по телефону:

[DataContract]
public class myInitializationData : ClientInitializationData
{
    [DataMember]
    public Dictionary<string, string> CultureNameLookup { get; set; }
}

Вот это базовый тип,

[DataContract]
public class ClientInitializationData
{
    [DataMember]
    public List<IServiceType> ServiceTypes { get; set; }
}

IServiceType - это интерфейс. Я понимаю, что не могу отправить интерфейс по проводам. Существует сущность EntityFramework ServiceType, реализующая интерфейс IServiceType:

public partial class ServiceType : IServiceType
{
    //...
}

Моя цель - отправить ServiceType сущностей по сети через myInitializationData контракт.

Мне запрещено украшать классы myInitializationData или ClientInitializationData с KnownType ServiceType, потому что эти классы совместно используются (связаны) с проектами Silverlight. Поэтому, если я украслю любой из этих классов с KnownType ServiceType, сторона (и) Silverlight не сможет скомпилироваться.

Вместо того, чтобы декорировать классы напрямую, я заключил контракт на обслуживание с ServiceKnownType ServiceType:

[ServiceContract]
[ServiceKnownType(typeof(ServiceType))]
public interface IService
{
    [OperationContract]
    myInitializationData InitializeClient();
}

Должно ли это работать?

При вызове IService.InitializeClient я получаю следующую ошибку на клиенте:

There was an error reading from the pipe: The pipe has been ended. (109, 0x6d).

Я включил отладку трассировки, но не нашел сообщений о сбое сериализации в трассировке для клиента или сервера.

Трассировка сервера:

  • Получает сообщение, когда-либо канал ( Действие: http://tempuri.org/IService/InitializeClient)
  • Кому: Выполнить ( IService.InitializeClient )
  • От: Выполнить ( IService.InitializeClient )
  • Отправляет сообщение по каналу. ( Действие: http://tempuri.org/IService/InitializeClientResponse)
  • Внимание! Failed System.ServiceModel.Channels.ServerSessionPreambleConnectionReader + ServerFramingDuplexSessionChannel
  • Внимание! Failed System.ServiceModel.Channels.ServiceChannel
  • Ответ на операцию вызвал исключение ( Экземпляр ObjectContext был удален и больше не может использоваться для операций, требующих подключения. )

Трассировка клиента:

  • Отправляет сообщение по каналу. ( Действие: http://tempuri.org/IService/InitializeClient)
  • Бросать исключение ( Произошла ошибка чтения из канала: канал завершен. (109, 0x6d). )

Если я выберу свойство ServiceTypes из ClientInitializationData DataContract, эта ошибка исчезнет. Поэтому я предполагаю, что это должно быть проблемой сериализации: интерфейса и KnownTypes, но WCF не претендует на наличие каких-либо проблем сериализации в трассировке, и я не уверен, что означает трассировка в этом случае.


Решение

Это не было проблемой KnownTypes. Это было результатом того, что LazyLoading был самопроизвольно включен в контексте объекта, определяющего тип ServiceType.

Хотя в трассировке нет упоминания о чрезмерном нарушении размера сообщения или буфера (на стороне клиента или сервера), я должен предположить, что включение LazyLoading в контексте EF заставило DataContractSerializer вызвать EF для выборки много записей, что, в свою очередь, привело к (попыткам) массивного графика на проводе. Серверная сторона просто (и неоднозначно) вышла из строя канала во время записи сообщения.

Возвращение LazyLoading в отключенное состояние в контексте EF с тех пор решило эту проблему.

1 Ответ

1 голос
/ 12 ноября 2010

Это не было проблемой KnownTypes.Это было результатом того, что LazyLoading был самопроизвольно включен в контексте объекта, определяющего тип ServiceType.

Хотя в трассировке нет упоминания о чрезмерном размере сообщения или размере буфера (на стороне клиента или сервера)), Я должен предположить, что включение LazyLoading для контекста EF заставило DataContractSerializer запустить EF для получения большого количества записей, что, в свою очередь, привело к попытке (попытке) массивного графика на проводе.Серверная сторона просто (и неоднозначно) вышла из строя канала во время записи сообщения.

Возвращение LazyLoading в отключенное состояние в контексте EF с тех пор решило эту проблему.

...