WCF - C#服务应该连续发送结果

时间:2011-06-11 19:51:48

标签: c# wcf streaming

由于这是一个很长的问题,悬崖笔记首先出现。

悬崖说明:
一个客户端向多个服务发送输入,他们继续工作并发送结果,直到客户端告诉他们停止或他们已达到预设的最大结果数。 < / p>

你知道如何实现这个,或者你有一个C#-example for sth。像这样?是WCF&amp;为此流式传输正确的工具集? (考虑结果是自定义对象,因此它与流式传输文件不完全相同)

更详细的问题定义:

情况:

  • 我可以完全控制客户端和服务的代码(不依赖于关闭的第三方内容)
  • 一切都在C#
  • 我们有一个客户想要完成一项任务,并且有几个相同的独立服务。 (相等=相同的服务软件,每个服务运行的硬件可能会有所不同 - >服务速度可能会有所不同)
  • 一项任务由“1000件作品”组成,彼此独立。
  • 在一项任务中,所有1000件工作都基于相同的输入数据。

我提到解决方案A + B,因为我认为它们有助于解释问题:

解决方案(A) - 缓慢的非平行方式:
1.客户将输入发送到一个服务 2.服务根据输入进行初始化 3.服务处理所有1000件工作
  (结果加起来(超快btw)所以1000件工作的结果与一个人的结果相同) 4.服务将结果发送给客户 5.客户收到结果并且很高兴

解决方案(B) - 并行更快的方式:
让我们说十个服务,所以我们将它平均分开,每个服务应该处理100个。

问题是某些服务可能比其他服务快得多,因此给每个相同的数字(100)比慢 必要。 此外,由于一项服务的速度可以改变,因此我们无法根据先验速度测试进行拆分 有些人甚至可能在处理过程中失败,这就是为什么我认为以下内容最适合我的目的。

解决方案(C) - 我想实现它的方式:
客户端向所有服务发出相同的请求。 (同样的要求仍然意味着任务得到并行处理,并行化对于我的问题来说非常容易1000件工作是如此独立,以至于做了1000次“第一”工作意味着我们已经完成了)

服务继续工作并发送结果,直到它被告知停止或处理了1000件工作。 一个结果被发送完成10件工作。 这意味着所有服务在任务上并行工作,当客户端获得所有服务回复的1000个结果时,它将发送停止信号。 这意味着通常没有单个服务应该达到1000,但是有1000个,我们已经涵盖了只有一个服务的情况,并且我们有一个故障保护,以避免在停止信号丢失时无限循环。 (客户既不需要等待也不能绝对确定停止信号已达到服务)

除了我们1000的目标之外扔掉额外的结果很好。

(相反,替代方案是对响应速度快于其他服务的服务提出后续请求  由于消息来回和额外的初始化而浪费时间的开销。  (添加.inits可以避免,但它会很复杂,你还有其他开销))

我基本上有解决方案/会知道如何实现A + B,但我不知道如何实现(C)。 如何在C#中实现客户端/服务架构,其中服务不断发送结果而不仅仅返回一个对象/值? (结果是自定义对象,顺便说一句) 有人知道C#-example-code where sth。那样实施了吗?流媒体是正确的方式吗?

我找到了"writing a custom stream" - 示例,但似乎从那里到我想要的东西还有很长的路要走。 (作为WCF-noob,我很容易就错了。)

2 个答案:

答案 0 :(得分:4)

WCF中的流不会以打开流的方式工作,将流返回到客户端,服务仍将生成流的结果。如果你想以这种方式工作,你必须更深入地直接使用套接字。在WCF中,必须在从操作返回之前写入流(我尝试从其他线程写入返回的流,但它不起作用)。 WCF中的流媒体仅用于数据传输。

我不喜欢你的任何解决方案。我会尝试:

  1. B的变体但是任务不会在前面平分。如果您有10个服务和1000个任务,则只有在服务返回结果后才会发送前10个任务(每个服务至少一个服务),它将获得另一个任务。如果任务可以在合理的时间内完成,则只需要对服务进行多次异步调用并等待响应。如果任何服务无法在定义的超时内完成任务,您将把任务发送到另一个服务。如果任务可以快速完成,您可以发送小批量而不是单个任务。如果任务完成需要很长时间,则需要进行双工通信。
  2. 使用事务性消息队列 - MSMQ。您的客户端将生成1000条消息到“生产者队列”,服务将逐个接收这些消息并处理它们。他们将结果作为消息发送到另一个“消费者队列”,其中客户端将获取结果并处理它们(每个结果必须与任务相关)。事务性队列将确保每个任务只能由单个服务处理,但如果服务失败或将发生事务超时,则该任务将可用于在另一个服务中处理。 MSMQ还提供了一些其他功能,例如队列,用于故障任务等。这是一点点高级方案。这种情况的主要问题可能是消息大小的限制(每条消息最多4MB)。
  3. 编辑:

    好的,因为你的澄清看起来你需要将相同的任务发送到多个服务,任务只会在相同的数据上触发一系列相同的计算。你可以用这种方式实现它:

    • 使用Net.tcp绑定构建双工服务
    • 服务将实现服务合同,该合同将具有开始计算和停止计算的操作(您可以使用IsInitiating的{​​{1}}和IsTerminating属性)
    • 服务将在启动操作中启动的单独线程中进行计算
    • 停止操作将中止计算线程
    • 客户端将实施回调合同以接收服务的结果
    • 当处理线程有结果(或多个结果)发回时,服务将调用客户端回调

    Here是使用OperationContract的双工服务的示例 - 请勿在您的方案中使用此绑定,因为如果您希望单个客户端与多个相同的服务进行通信则要复杂得多over duplex HTTP。

答案 1 :(得分:0)

您所描述的解决方案(C)听起来非常适合异步WCF。其中一些可能会有所帮助...

Synchronous and Asynchronous Operations
Asynchronous Programming Design Patterns
How to: Call WCF Service Operations Asynchronously