c# - 使用非单向方法的 WCF 中的竞争条件

标签 c# .net wcf race-condition nettcpbinding

我正在设计一个客户端-服务器聊天应用程序(事实上我不是,但让我们假设我是:)),我对我经历过的一些竞争条件感到有点困惑。

假设我有以下代码:

public interface IServer
{
  [OperationContract(IsOneWay = false)]
  [FaultContract(typeof(ChatException))]
  void BroadcastMessage(string msg);
}

public class Server : IServer 
{
  void BroadcastMessage(string msg) // I'm not mentionning the try/catch/throw FaultException here for readability purposes
  {
    foreach (IClientCallback c in callbacks){
      c.ReceiveMessage(msg);
    }

  }
}

public interface IClientCallback
{
  [OperationContract(IsOneWay = true)]
  void ReceiveMessage(string s);
}

这里是绑定(bind)配置的摘录:

<endpoint address="" 
binding="netTcpBinding" 
bindingConfiguration="DuplexBinding" 
contract="IServer" />

 <binding name="DuplexBinding" sendTimeout="00:01:00">
   <reliableSession ordered="true" inactivityTimeout="00:05:00" enabled="true"/>
   <security mode="None">
     <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
     <message clientCredentialType="Windows" />
   </security>
 </binding>

这当然是某种伪 C#,为了清楚起见,我删除了很多不相关的代码。

现在进入正题: 这段代码不会工作。当我调用 BroadcastMessage 时,该方法永远不会返回,并且最终在客户端出现超时。如果我在服务器端进行调试,一切看起来都很好(我从 BroadcastMessage 方法返回,完全按照预期,并且我不会阻止任何 ReceiveMessage 单向调用)

以下是修复此代码的两种方法:

  1. 删除FaultContract并将BroadcastMessage方法声明为oneway=true
  2. 向除初始发件人之外的所有人广播消息

我的第一个猜测是客户端正在等待服务器返回,因此无法处理来自服务器的传入 ReceiveMessage 调用,从而阻塞服务器,但 ReceiveMessage 被声明为单向,并调试服务器显示它不会阻止对 ReceiveMessage 的任何调用

现在,我的问题:

  • 发生了什么事?

  • 还有其他方法可以解决此问题吗? (也许通过调整绑定(bind)配置?)

  • 假设我选择修复 2(即不广播回发件人),如果服务器在我等待自己的消息时调用我的 ReceiveMessage 回调(因为其他人向我发送了一条消息),会发生什么情况BroadcastMessage 调用完成吗?

  • 我了解到 OneWay 调用并不完全是单向的,并且服务器仍然等待来自另一端的 HTTP 响应。有这方面的详细信息吗?具体来说,当客户端在远程调用中被阻止时,是否能够响应此类 http 响应?

编辑:服务器端使用 Console .net 3.5,客户端使用 Winforms .net 3.5

最佳答案

这听起来像是一个死锁,可能是由于同步上下文造成的。什么是客户?维窗体?世界和平基金会? WCF 尊重同步上下文,这对于 winforms 和 WPF 来说意味着“切换到 UI 线程”。如果您在 UI 线程上发出阻塞请求,则游戏结束。

尝试在后台线程上执行 WCF 请求,以便 UI 线程可用于处理传入请求;这可以像使用 ThreadPool 或 BackgroundWorker 一样简单。

关于c# - 使用非单向方法的 WCF 中的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/472351/

相关文章:

.net - 使用 Regex.Replace 时如何处理多个匹配项

c# - 服务类可以以及如何继承普通类?

c# - 不使用BouncyCaSTLe的C#中的数字签名

c# - 具有自动实现属性和构造函数初始值设定项的结构

c# - 为什么我收到 "' 某个类'不包含 'some method' 的定义“错误,而该类具有该方法?

c# - MEMCACHED get 方法总是返回 null

c# - 如何通过正则表达式屏蔽输入? 1112223333 或 1112223333444

c# - 为什么我在此代码中收到 IndexOutOfRangeException?

wcf - 从经典 asmx 切换到 wcf 的好处

windows - 在 WCF 中编写 Windows 服务