2011-01-05 15 views
7

Estoy implementando mi primer servicio REST en .NET 4 y he encontrado algo inesperado. Parece que no entiendo el funcionamiento subyacente de ServiceModel de Microsoft, pero no pude encontrar la respuesta de la manera tradicional.Uso del conjunto de subprocesos en la implementación del servicio REST .NET

Para poner en práctica mi servicio web que estaba siguiendo los pasos de este tutorial: http://blogs.msdn.com/b/endpoint/archive/2010/01/06/introducing-wcf-webhttp-services-in-net-4.aspx

funciona el servicio. Lo que me sorprendió fue que Application_BeginRequest y Application_EndRequest en Global.asax son llamados por diferentes subprocesos. Al observar el seguimiento de la pila, parece que estos subprocesos se basan en algún tipo de grupo de subprocesos.

Sin hacer algunas refactorizaciones, este es un problema para nosotros ya que siempre asumíamos que una única solicitud siempre se ejecutaría en el mismo subproceso, por lo que mantendríamos algunas variables almacenadas en el almacenamiento local de subprocesos. Las variables se inicializan en Application_BeginRequest y se lanzan en Application_EndRequest. Parece que con ServiceModel este no es el enfoque correcto.

Mis preguntas son:

  1. ¿Puedo hacer ninguna suposición sobre los flujos en ejecución mi código cuando estoy usando ServiceModel?
  2. ¿Hay alguna forma de restringir la ejecución a un único hilo? ¿Esto sería malo por alguna razón?
  3. ¿Cuál es la forma correcta de almacenar una variable durante la duración de la solicitud cuando se utiliza ServiceModel?

Gracias.

+0

Actualización a la pregunta inicial. Su único hilo llama a Application_BeginRequest y un hilo diferente ejecuta el código de servicio y ejecuta Application_EndRequest. Cambiar los parámetros de Service Behavior no hizo nada. Cualquier ayuda sería muy apreciada. – Alex

+0

Parece que está usando material de compatibilidad asp.net o intenta hacerlo. ¿Has intentado implementar tus cosas como despachadores de mensajes o cualquier otro punto de extensión wcf (en lugar de usar asp.net)? – sisve

+0

@Simon Svensson Estaba siguiendo el tutorial de Microsoft http://blogs.msdn.com/b/endpoint/archive/2010/01/06/introducing-wcf-webhttp-services-in-net-4.aspx. Lo cual parece usar compatibilidad asp.net. ¿Qué sería diferente si se usa el otro enfoque? ¿Hay algún buen lugar donde pueda leerlo? ¡Gracias! – Alex

Respuesta

0

Es posible que desee ver el atributo [ServiceBehavior] en su implementación de servicio, ya que admite argumentos para controlar cuántas instancias se crean y qué modelo de subprocesamiento se utiliza.

http://msdn.microsoft.com/en-us/library/cc681240.aspx

Cuando se tiene

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, 
       ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class MyService : IMyService 

su servicio funcionará como un conjunto unitario pero con múltiples hilos - hasta un umbral establecido en la configuración de WCF - poner en sus métodos. Para forzarlo a ejecutar solo en un hilo y, por lo tanto, serializar solicitudes de entrada, configure ConcurrencyMode.Single.

Como alternativa, puede girar hasta una nueva instancia de su servicio para cada llamada:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, 
       ConcurrencyMode = ConcurrencyMode.Single)] 
public class MyService : IMyService 

La instancia tendrá sólo un hilo para acceder a él. De hecho, cuando tiene InstanceContextMode.PerCall, el modo ConcurrencyMode se ignora porque siempre es "Único" y cada instancia se ejecuta en su propio hilo.

+0

Gracias Lawrence. he fijado [ServiceBehavior (InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)] todavía llamando Thread.CurrentThread.GetHashCode(). ToString() en Application_BeginRequest y Application_EndRequest vuelve diferente valores, ¿estoy haciendo algo incorrectamente? – Alex

2

Una cosa que sugeriría es considerar el uso de los ganchos WCF en lugar de los métodos Application_BeginRequest y Application_EndRequest. Cuatro ejemplo, aquí son cuatro de los ganchos más útiles:

AfterReceiveRequest -> BeforeCall -> llamada al método -> AfterCall -> BeforeSendReply

Hay ganchos son bastante poderosos. Puede inspeccionar los parámetros antes de llamar a su método (centralizar algunos registros en un lugar) y hacer todo tipo de otras cosas útiles.Estos no son los únicos ganchos disponibles, también hay otros que uso. Por ejemplo, GetInstance me permite anular la creación del objeto de clase de servicio (para que pueda usar frameworks de inyección de dependencias, etc.).

Cuando uso el modo de concurrencia por llamada, estos ganchos más la llamada al método TODO se llama en el mismo hilo. Espero que esto ayude. Puedo proporcionar enlaces a la implementación de estos enlaces si lo desea.

Cheers

Cuestiones relacionadas