WCF中的异步流

本文关键字:异步 WCF | 更新日期: 2023-09-27 17:58:38

我正在使用WCF进行流式处理,我有一个问题,关于MSDN关于WCF中的大数据和流式处理的文章中关于"启用异步流式处理"的段落意味着什么。

要启用异步流,请添加DispatcherSynchronizationBehavior端点对服务的行为主机并将其CCD_ 2属性设置为CCD_。我们有还添加了在发送时进行真正异步流传输的功能一边这提高了服务在以下场景中的可扩展性正在将消息流式传输到多个客户端,其中一些客户端速度较慢阅读可能是由于网络拥塞或根本没有阅读。在这些场景中,我们现在不阻塞每个客户端的服务。这确保了服务能够处理更多的客户端,从而提高了服务的可扩展性。

我知道上面的意思是我添加

<behaviors>
  <endpointBehaviors>
    <behavior name="AsyncStreaming">
      <dispatcherSynchronization asynchronousSendEnabled="true" />
    </behavior>
  </endpointBehaviors>
  ...

到我的web.config文件,并在我的端点中引用AsyncStreaming行为,但是我不明白这些步骤对我来说能完成什么。我需要修改我的代码来利用这种异步性吗?

同样在一个类似的主题上(但如果太不同,我将把它转移到一个新的问题上),在WCF中使用异步/等待如何影响使用Streams?我可以在我的服务合同中做Task<Stream> Foo()吗?我进行了一些数据库调用,最终将其结果封装到一个自定义流中,并从WCF服务返回该流。能够使用ExecuteDataReaderAsync()之类的东西非常有用,在处理流式而不是缓冲消息时,我还能使用它吗?

我已经测试过它,我知道它使用Tasks"有效",但我不知道这样做是否会导致函数返回到"缓冲"模式,比如当你为函数提供多个参数时(请参阅同一MSDN页面上"流传输编程模型"的第3段),我不知道如何检查是否发生了这种情况。

WCF中的异步流

我通过.NET参考源将其追溯到RequestContext。显然,ChannelHandler.sendAsynchronously字段控制消息回复是异步完成(通过RequestContext.BeginReply/EndReply APM方法)还是通过RequestContext.Reply同步完成。

据我所知,所有这些都是释放一个服务器端线程,该线程被返回到池中,否则,只要Stream对象在服务器上是活动的,它就会在RequestContext.Reply内忙于将流"泵送"到客户端。

这看起来是完全透明的,所以我认为您可以安全地使用基于asyncTAP的合约方法并返回Task<Stream>。例如,在另一种合同方法中,您可以执行await Stream.WriteAsync

当你到达那里时,请分享你的实际经验作为你自己的答案,我对细节非常感兴趣:)

关于复杂主题的好问题。我已经实现了一个流式WCF服务,以容纳巨大(高达2GB)的下载,但我对这个AsyncStreaming=True业务也有点困惑,因为WCF已经是异步的(因为每个连接的客户端都有自己的线程,并异步请求和接收),只要

 <ServiceBehavior(ConcurrencyMode:=ConcurrencyMode.Multiple, InstanceContextMode:=InstanceContextMode.PerCall)>

但你必须修改你的代码才能使流媒体工作。即使您有Binding.TransferMode=TransferMode.Streamed,如果您不更改代码,程序也会恢复到缓冲,以便您的上传和下载功能A)获取和返回流,B)上传和下载函数实现如下功能:

//oBuffer is your content
if (oBuffer != null) {
    oStream = new MemoryStream(oBuffer);
    if (oStream.CanSeek) {
        oStream.Seek(0, SeekOrigin.Begin);
    }
    return oStream;
}

这是一篇不错的HowTo文章,我用它作为指南:http://www.codeproject.com/Articles/166763/WCF-Streaming-Upload-Download-Files-Over-HTTP