2010-02-17 4 views
5

El cliente envía una gran cantidad de mensajes al servidor desde un solo hilo, en un solo canal WCF.¿Por qué mi mensaje se procesa fuera de servicio en un solo canal WCF TCP (con ConcurrencyMode.Reentrant)?

El cliente envía el mensaje con BeginMyMethod (x, b) ya que no desea bloquearlo mientras se procesa.

Tenemos mensajería confiable activada, ya que no deseamos perder ningún mensaje, ni hacer que se descompongan.

Sin embargo, los mensajes se envían a varios hilos en el servidor, por lo que están en proceso fuera de servicio.

No podemos hacer que el servidor sea de una sola hebra, ya que no deseamos que una solicitud de larga ejecución de un cliente bloquee otros clientes.

Así que sólo desea procesar todos los mensajes que provienen de un solo cliente (por un solo canal ) en fin con único mensaje de cada cleint está procesando a la vez.

Esto sería fácil para la programación de socket raw, sin embargo, ¿cómo puedo obtener WCF para que funcione como yo lo desee?


Ahora estoy pensando que ConcurrencyMode.Reentrant no se comporta bien cuando se utiliza con InstanceContextMode.Single Si fijo ConcurrencyMode.Single utilizar los mensajes se mantienen en orden, pero mi devoluciones de llamadas punto muerto.

(La prueba que obtiene los mensajes fuera de servicio no tiene devoluciones de llamada y no realiza ninguna llamada WCF saliente, por lo que esperaría que ConcurrencyMode.Reentrant se comporte igual que ConcurrencyMode.Single en esa prueba determinada, pero no lo hace)

I a no utilizar los archivos de configuración de WCF, el código es:

serviceHost = new ServiceHost(this); 
serviceHost.AddServiceEndpoint(
    typeof(IAllEngineManagersAsyncCallbacks), 
    new NetTcpBinding(SecurityMode.None, true), 
    endPointAddress); 
+0

¿Qué es un "presbiterio"? Usaste esa palabra tres veces. ¿Te refieres al canal? –

+0

¿Puede publicar su configuración de enlace personalizada? – tgeros

Respuesta

3

ahora han trabajado alrededor de este problema:

  • Cambiando todos mis devoluciones de llamadas desde el servidor al cliente para ser OneWay
  • El uso de un despachador en el cliente antes de pasar cualquier devolución de llamada desde la servidor, por lo que el código de cliente nunca llama el Sever desde dentro de una devolución de llamada
    • el objeto de devolución de llamada del cliente está marcado con CallbackBehavior (UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Único)
    • Al ejecutar en Winform o WPF utilizo SynchronizationContext. Publicar para enviar las devoluciones de llamada
    • Cuando el cleint es una consola o un servidor de Windows utilizo un custom depatcher.
  • Dejé que use ConcurrencyMode.Single tanto en el servidor como en el cliente.

Ahora está funcionando como se esperaba.
(BeginMyMethod (x, b) sigue siendo utilizado para enviar contactado desde el cliente al servidor)

(ConcurrencyMode.Reentrant parece liberar a veces el bloqueo, incluso cuando la llamada WCF no se hace en el hilo que algunos está procesando el mensaje entrante, simplemente no es útil ya que Reentrant estaba en DCOM)

0

creo que el modo reentrante implica que se permite ser procesados ​​fuera de mensajes. El comportamiento normal de dicho servicio sería: obtener un mensaje, poner en cola los hilos internos para procesar y, cuando esté listo, notificar al cliente sobre el resultado. ¿Entonces quizás su servicio reciba mensajes en el orden correcto pero algunos de ellos son quiker para procesar y regresar antes que otros?

+0

según lo entiendo, Reentrant solo deja un nuevo mensaje cuando realizo una llamada al wcf saliente. El caso de prueba que falla no realiza ninguna llamada saliente. –

2

Si está utilizando los métodos async BeginXXX generados, estos se ejecutan en un subproceso ThreadPool. Entonces, aunque haya enviado los mensajes en un orden definido, nadie le garantiza en qué orden ThreadPool ejecuta las solicitudes.

+0

¿Alguien más puede confirmar esto? –

+1

Cuando escribimos este código, usamos myDelegate.BeginInvoke (a, b) y luego llamamos al método wcf desde el delegado. Nuestra prueba falló TODO el tiempo con mensajes que se salieron de orden debido a las solicitudes de ThreadPool en cola. Entonces, los métodos async de BeginXXX generados están haciendo algo diferente. –

Cuestiones relacionadas