Почему мое сообщение быть обработанным не в порядке по единственному каналу TCP WCF (с ConcurrencyMode. Повторно используемый)?

Клиент отправляет много сообщений к серверу от единственного потока по единственному каналу WCF.

Клиент отправляет сообщение с BeginMyMethod (x, b), поскольку это не хочет блокироваться, в то время как они обрабатываются.

Нам включили надежный обмен сообщениями, поскольку мы не хотим потерять любые сообщения или сделать, чтобы они стали неисправными.

Однако сообщения отправляются на нескольких потоках на сервере, так процесс не в порядке.

У нас не может быть сервера, являющегося единственным, распараллелил, поскольку мы не хотим, чтобы длительный запрос от одного клиента заблокировал другие клиенты.

Таким образом, я просто хочу обработать все сообщения, которые появляются от единственного клиента (по одному каналу) в порядке только с одним сообщением от каждого клиента, обрабатываемого за один раз.

Это было бы легко для программирования неструктурированного сокета, однако как я заставляю WCF работать, как я желаю?


Я теперь думаю тот ConcurrencyMode. Повторно используемый не ведет себя хорошо при использовании с InstanceContextMode. Единственный, Если я установил, используют ConcurrencyMode. Единственный сообщения поддерживаются в порядке, но моя мертвая блокировка обратных вызовов.

(Тест, который получает сообщения не в порядке, не имеет никаких обратных вызовов и не выполняет исходящих вызовов WCF, таким образом, я ожидал бы ConcurrencyMode. Повторно используемый для поведения того же как ConcurrencyMode. Единственный в том данном тесте, но это не делает),

Я не использование любых файлов конфигурации WCF, код:

serviceHost = new ServiceHost(this);
serviceHost.AddServiceEndpoint(
   typeof(IAllEngineManagersAsyncCallbacks),
   new NetTcpBinding(SecurityMode.None, true),
   endPointAddress);
5
задан Ian Ringrose 25 February 2010 в 08:19
поделиться

3 ответа

Сейчас я решил эту проблему следующим образом:

  • Изменил все мои обратные вызовы от сервера к клиенту на OneWay
  • Использую диспетчер в клиенте перед передачей любого обратного вызова от сервера, поэтому клиентский код никогда не вызывает сервер из обратного вызова.
    • Объект клиентского call-back помечен CallbackBehavior(UseSynchronizationContext=false, ConcurrencyMode=ConcurrencyMode.Single)
    • При работе в Winform или WPF я использую SynchronizationContext. Post для депатчинга обратных вызовов
    • Когда клиентом является консоль или сервер Windows, я использую пользовательский депатчер.
  • Это позволяет мне использовать ConcurrencyMode.Single как на сервере, так и на клиенте.

Теперь все работает, как ожидалось.
(BeginMyMethod(x, b) все еще используется для отправки сообщений с клиента на сервер)

(ConcurrencyMode.Reentrant, кажется, иногда освобождает блокировку, даже когда вызов WCF не сделан на каком-то потоке, который обрабатывает входящее сообщение, это просто не полезно, как Reentrant был в DCOM)

.
3
ответ дан 14 December 2019 в 19:11
поделиться

Я думаю, что режим повторного входа подразумевает, что вы разрешаете обработку сообщений не по порядку. Нормальное поведение такой службы: получить сообщение, поставить в очередь для обработки внутренними потоками и, когда это будет сделано, уведомить клиента о результате. Так что, возможно, ваша служба получает сообщения в правильном порядке, но некоторые из них быстрее обрабатываются и возвращаются раньше, чем другие?

0
ответ дан 14 December 2019 в 19:11
поделиться

Если вы используете сгенерированные асинхронные методы BeginXXX, они выполняются в потоке ThreadPool. Таким образом, хотя вы отправляете сообщения в определенном порядке, никто не гарантирует вам, в каком порядке ThreadPool выполняет Запросы.

2
ответ дан 14 December 2019 в 19:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: