为什么我的消息在单个WCF TCP通道(使用ConcurrencyMode.Reentrant)上无序处理?

Ian*_*ose 5 wcf multithreading asynchronous

客户端通过单个WCF通道从单个线程向服务器发送大量消息.

客户端使用BeginMyMethod(x,b)发送消息,因为它们在处理时不希望阻止.

我们打开了可靠的消息,因为我们不希望丢失任何消息,或者让它们失灵.

但是,消息正在服务器上的多个线程上发送,因此正在处理乱序.

我们不能让服务器是单线程的,因为我们不希望来自一个客户端的长时间运行请求阻止其他客户端.

所以,我只是希望处理所有来自消息单个客户机(在单一通道上)以便仅一个消息从每个cleint在一个时间被处理.

对于原始套接字编程来说这很容易,但是如何让WCF按照我的意愿工作?


我现在认为ConcurrencyMode.Reentrant在与InstanceContextMode.Single一起使用时表现不佳.如果我设置使用ConcurrencyMode.Single,则消息按顺序保留,但我的回调死锁.

(无序地获取消息的测试没有回调,也没有进行任何传出的WCF调用,所以我希望ConcurrencyMode.Reentrant在给定测试中的行为与ConcurrencyMode.Single相同,但它没有)

我没有使用任何WCF配置文件,代码是:

serviceHost = new ServiceHost(this);
serviceHost.AddServiceEndpoint(
   typeof(IAllEngineManagersAsyncCallbacks),
   new NetTcpBinding(SecurityMode.None, true),
   endPointAddress);
Run Code Online (Sandbox Code Playgroud)

Ian*_*ose 3

我现在已经通过以下方法解决了这个问题:

  • 将我从服务器到客户端的所有回调更改为 OneWay
  • 在从服务器传递任何回调之前在客户端中使用调度程序,因此客户端代码永远不会从回调中调用服务器
    • 客户端回调对象标记有 CallbackBehavior( UseSynchronizationContext=false , ConcurrencyMode=ConcurrencyMode.Single)
    • 在 Winform 或 WPF 中运行时,我使用 SynchronizationContext。发布以分派回调
    • 当客户端是控制台或 Windows 服务器时,我使用自定义 depatcher
  • 因此,让我在服务器和客户端上使用 ConcurrencyMode.Single。

现在它正在按预期工作。
(BeginMyMethod(x, b) 仍然用于从客户端向服务器发送消息)

(ConcurrencyMode.Reentrant 有时似乎会释放锁,即使未在正在处理传入消息的某个线程上进行 WCF 调用,它也不像 DCOM 中的 Reentrant 那样有用)