我可以创建一个多个调用不相互阻塞的 WCF

Posted

技术标签:

【中文标题】我可以创建一个多个调用不相互阻塞的 WCF【英文标题】:Can I create a WCF where multiple calls are not blocking each other 【发布时间】:2014-08-10 07:34:17 【问题描述】:

我有一个使用 HTTP 连接调用 WCF 服务的 WebAPI 应用程序。对 WebAPI 的调用来自用户浏览器。 WCF 服务托管在单独的 IIS 应用程序中。

由于一些遗留代码,WCF 服务中的一种方法是一个长时间运行的进程,例如30 秒,它会生成一个大字节数组,然后我们可以返回并继续传递。

还有另一种方法不是长时间运行的过程,应该立即返回。然而,当客户端调用长进程时,另一个方法被阻止完成,直到长进程完成。

我尝试了很多方法,例如将以下内容添加到服务中:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode=InstanceContextMode.PerCall)]

并将以下内容添加到配置中:

  <system.net>
    <connectionManagement>
      <add address = "*" maxconnection = "100" />
    </connectionManagement>
  </system.net>

并关闭会话状态:

<sessionState mode="Off" />

但是,我无法让这些调用并行工作。我知道这与 WCF 服务防止会话问题的方式有关,但我已关闭 aspNetCompatibilityEnabled 并且我不使用 HttpContext 会话或缓存,所以我不确定是什么导致了阻塞。

有什么想法可以让这些调用并行工作而无需对它们进行重大返工?

【问题讨论】:

你试过“UseSynchronizationContext = false”吗?参考。 ***.com/a/22785352/1315873 感谢@Fil 的建议,但我已经尝试过了,但仍然没有运气。第一个调用仍然阻止第二个调用启动。 不知道是不是客户端的问题。 WCF 调用是阻塞的,即客户端仅在服务方法结束后继续执行。如果服务方法异步执行长时间工作,那么它可以很快返回,客户端可以继续执行并且(如果服务器上的一切正常)可以调用第二个(短)WCF 方法。可能同时执行两个不同的客户端调用(如果服务器正常),但在这种情况下,来自同一个客户端的两个调用必须按顺序完成(等待第一个 WCF 调用返回)。 尝试将 Windows Server AppFabric 添加到您的 IIS 部署中。然后点击应用;点击Configure...,查看Throttling页面,了解Maximum concurrent calls 您好,我也遇到了同样的问题,请问您找到解决方法了吗? 【参考方案1】:

这可能不是最好的解决方案,但我发现将可靠会话设置为 false 似乎可以解决所描述情况下的问题。我个人最终没有使用它,但我会发布它以防万一其他人需要它。

这是我在 wcf web.config 中使用的设置。不要忘记在客户端也将可靠会话设置为 false。

  <wsHttpBinding>
    <binding name="BindingName" receiveTimeout="00:20:00" maxReceivedMessageSize="10485760">
      <reliableSession enabled="false"/>
      <security mode="None">
        <transport clientCredentialType="None" proxyCredentialType="None" />
        <message establishSecurityContext="true" clientCredentialType="None" />
      </security>
    </binding>
  </wsHttpBinding>

【讨论】:

【参考方案2】:

默认情况下,ReliableSession 确保消息按发送顺序传递。看看这个:System.ServiceModel.ReliableSession.Ordered

您需要将Ordered 设置为false

它在内部设置ReliableSessionBindingElement 的值。如果这仍然不起作用,您还可以尝试将ReliableSessionBindingElementFlowControlEnabled 的值设置为false

【讨论】:

以上是关于我可以创建一个多个调用不相互阻塞的 WCF的主要内容,如果未能解决你的问题,请参考以下文章

NetTcpBinding 和 async/await WCF 阻塞

如何在不阻塞主线程的情况下使用 join() 创建多个 C++ 线程?

WCF 仅异步操作

如何运行命令行 FFMPEG 并接受多个管道(视频和音频)而不阻塞第一个输入?

如何在多个任务之后继续而不阻塞 UI 线程?

简单理解线程--阻塞,interrupt