C# 获取IEnumerable<;T>;使用NetTcpBinding WCF服务的语义?

C# 获取IEnumerable<;T>;使用NetTcpBinding WCF服务的语义?,c#,wcf,protobuf-net,nettcpbinding,remoteobject,C#,Wcf,Protobuf Net,Nettcpbinding,Remoteobject,首先,这不是重复的,我想我理解WCF架构只允许传输可以填充到消息中的具体类型 第二,我们的设置不是一般服务,而是通过C#+WCF++(仅限)连接一组专有应用程序,因此我们可能有更多的空间来使用一些技巧,这些技巧需要更具约束力的中立性 第三,提出不同的RPC或消息传递框架既不适合我,也不适合这个问题 就本问题而言,“IEnumerable语义”是: 返回的序列可以任意大——因此不可能将序列转换为列表或类似列表 目前还不知道会返还多少物品 调用者只需使用foreach即可完成 在本地程序集中

首先,这不是重复的,我想我理解WCF架构只允许传输可以填充到消息中的具体类型

第二,我们的设置不是一般服务,而是通过C#+WCF++(仅限)连接一组专有应用程序,因此我们可能有更多的空间来使用一些技巧,这些技巧需要更具约束力的中立性

第三,提出不同的RPC或消息传递框架既不适合我,也不适合这个问题


就本问题而言,“IEnumerable语义”是:

  • 返回的序列可以任意大——因此不可能将序列转换为
    列表
    或类似列表
  • 目前还不知道会返还多少物品
  • 调用者只需使用
    foreach
    即可完成

在本地程序集中,C#接口的外观如下所示:

interface IStuffProvider {
  IEnumerable<Stuff> GetItems(); // may open large file or access database
}
    [OperationContract]
    ReadToken StartReadingLines(...);

    [OperationContract]
    // return next batch of items (empty list if no more available)
    List<Stuff> ReadNextLines(ReadToken readToken);

    [OperationContract]
    void FinishReadingLines(ReadToken readToken);
接口IStuffProvider{
IEnumerable GetItems();//可以打开大文件或访问数据库
}
您不能将其直接映射到WCF服务。可能达到同样效果的东西可能如下所示:

[ServiceContract(SessionMode = SessionMode.Required)]
interface IStuffService {
  [OperationContract]
  void Reset(); // may open large file or access database
  [OperationContract]
  List<Stuff> GetNext(); // return next batch of items (empty list if no more available)
}
[ServiceContract(SessionMode=SessionMode.Required)]
接口IStuffService{
[经营合同]
void Reset();//可以打开大文件或访问数据库
[经营合同]
List GetNext();//返回下一批项目(如果没有更多可用项,则返回空列表)
}
当然,使用
IStuffService
比使用
IStuffProvider
更容易出错,并且添加到混合中,比许多使用场景都需要在同一台机器上同时使用服务和客户端更容易出错,因此对于“用户代码”来说,意识到涉及“网络”并不是特别重要,用户代码只对简单的界面感兴趣

当然,一个选项是有一个客户端接口包装器实现,它公开
IStuffProvider
,并在内部转发到并使用
IStuffService
。 然而,似乎不必维护两个接口是非常可取的,一个用于用户代码,一个仅用于WCF通信,特别是因为这些应用程序都是紧密耦合的,因此额外的抽象似乎只是开销

我们这里有哪些WCF选项?



请注意,在阅读之后,这个解决方案似乎很糟糕,因为我仍然需要客户端的包装器,并且服务接口会变得更复杂,在我的情况下没有真正的好处:我不需要最大的二进制传输效率,我希望实现+维护效率良好。

不久前,我们遇到了相同的WCF“限制”在我们的项目中。简而言之,我们以

interface IStuffProvider {
  List<Stuff> GetItems(int page, int pageSize); // may open large file or access database
}
接口IStuffProvider{
List GetItems(int page,int pageSize);//可以打开大文件或访问数据库
}

是的,它与
IEnumerable GetItems()不同是的,当在已经收到的页面上添加/删除某些项时,我们可能会遇到麻烦。是的,如果服务器使用的是
IEnumerable
项,则需要对服务器端进行一些调整。但它仍然是严格键入的,不会给客户端或服务器带来太多额外的逻辑。

我最后做的是:

a) OO接口
IStuffProvider
GetLines()
成员如上所述

b) WCF服务接口(及其实现)实现了如下访问模式:

interface IStuffProvider {
  IEnumerable<Stuff> GetItems(); // may open large file or access database
}
    [OperationContract]
    ReadToken StartReadingLines(...);

    [OperationContract]
    // return next batch of items (empty list if no more available)
    List<Stuff> ReadNextLines(ReadToken readToken);

    [OperationContract]
    void FinishReadingLines(ReadToken readToken);

也许你可以使用WCF提供的?(我已经有一段时间没有使用WCF了,所以我不确定它是否合适…)@AasmundEldhuset-当然是一本值得一读的书。虽然似乎有很多字符串。WCF往往是这样的,不是吗?;-)任意大=>流式绑定。不需要动脑筋。@Lucas-到目前为止,我还没有掌握流式绑定是否可以应用于任意类型,或者它是否只适用于
byte5
怎么办?如果多次请求相同的数据怎么办?)等等。这可能是一个很好的“替代”答案。至少它看起来技术含量低,易于维护(如果不使用的话)。@TJ好吧,正如我所写的,我们在项目中面临着同样的限制,而且(无论多么令人伤心)这是我们的问题的答案。因此(也只有这样)我写了这篇文章作为回答。无论如何,我很高兴看到“真实”的答案。是的,这既不是批评也不是要求,对于这两个,我总是使用评论;)@MartinBa是的,这种方法远不是完美的,但它是我们解决“顺序”访问问题的方法,我们可以在需要时中断访问,而不需要获得其余的访问。