2009-12-01 17 views
16

Escribí un servicio WCF, pero los datos almacenados en la implementación del servicio no persisten entre llamadas, ni siquiera si están almacenados en una variable estática. ¿Que puedo hacer?Cómo escribir un servicio WCF con almacenamiento persistente en memoria?

La implementación del servicio es la siguiente:

public class Storage : IStorage 
{ 
    protected static object[] _data; 

    #region IStorage Members 

    public void Insert(object[] data) 
    { 
     lock (_data) 
     { 
      _data = _data.Concat(data).ToArray(); 
     } 
    } 

    public object[] SelectAll() 
    { 
     lock (_data) 
     { 
      return (object[])_data.Clone(); 
     } 
    } 

    #endregion 
} 

El host de servicio es una aplicación de consola:

static void Main(string[] args) 
{ 
    ServiceHost serviceHost = 
     new ServiceHost(typeof(TimeSpanStorage)); 
    serviceHost.Open(); 
    Console.WriteLine("Service running. Please 'Enter' to exit..."); 
    Console.ReadLine(); 
} 

Respuesta

17

Por defecto, WCF instanceMode se establece en Por llamada, lo que significa que los datos utilizados en el servicio son específicos de ese cliente para esa llamada de método.

En su intento aplicación añadiendo

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

Esto hace que el servicio esencialmente un producto único.

+1

Establecer el modo de contexto como 'Único 'no es necesariamente lo correcto, eso no permitirá el estado por transacción. Usar una 'DurableOperation' es una opción mucho mejor. –

+0

Acepto que no permitirá el control transaccional de un servicio duradero. Y el patrón de singleton tiene sus límites cuando quieres escalar. La "información ... no persiste entre llamadas" me hizo pensar que el OP estaba buscando algo simple. – MattC

+0

Configurar InstanceContextMode en Single es una idea horrible: su clase de servicio WCF ahora es un singleton, y ha serializado el manejo de todas sus solicitudes (eliminando cualquier rendimiento), o necesita lidiar con problemas de subprocesamiento múltiple (difícil y propenso a errores) La mejor opción son los servicios duraderos, que realmente simplemente almacenan su estado en una tienda persistente (por ejemplo, una base de datos). –

8

Lo que está buscando que hacer es crear un durable service:

Los servicios de WCF Durable son servicios de WCF en los cuales las operaciones pueden recordar los valores de las variables privadas (= el estado del servicio) entre se reinicia el cliente serivcehost y/o .

+0

gracias por su respuesta. No encontré una opción de persistencia de memoria dentro de los servicios duraderos. ¿Hay alguna? ¿O solo las opciones de persistencia de la base de datos? –

+2

El enlace ya no parece apuntar al artículo original –

+0

Ver http: // msdn.microsoft.com/en-us/library/vstudio/bb628514(v=vs.90).aspx – Jono

3

¿Desea conservar los datos más allá de la duración de la instancia de su ServiceHost? Si es así, entonces estoy de acuerdo en que un servicio duradero tiene sentido.

Sin embargo, si solo desea conservar los datos entre llamadas a su servicio WCF mientras el servicio está activo, entonces un servicio duradero es excesivo en mi humilde opinión. Usar datos estáticos es perfectamente aceptable; es precisamente lo que hago en mi proyecto WCF. De hecho, el código que ha mostrado debería funcionar, entonces aquí está sucediendo algo más.

¿Es el método Main() realmente como lo has mostrado? Si es así, entonces eso es un problema. Tan pronto como se inicia la aplicación de consola habilitada para WCF, se cierra de inmediato, llevándose el servicio WCF. Debe tener algo de lógica para mantener activa la aplicación de consola porque el servicio WCF solo permanecerá 'alojado' mientras se ejecuta la aplicación de la consola.

Si este no es el problema, házmelo saber y agregaré el código completo de una aplicación simple que demuestra cómo hacerlo.

+0

No, el método principal tenía una llamada Console.ReadLine. La pregunta fue editada para reflejar esto. –

+0

¿Qué significa "mientras el servicio está vivo"? Significa "mientras se está ejecutando la aplicación de consola de host de servicio"? –

+2

@Jader Dias: Sí, si solo desea mantener los datos mientras se ejecuta la aplicación de consola 'ServiceHost', entonces no hay razón para utilizar el enfoque de servicio duradero. El enfoque de servicio duradero funcionará, pero también lo hará el enfoque de datos estáticos (de nuevo, eso es lo que estoy usando en mi proyecto de servicio WCF). –

-4

Añadir:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] 

Por encima de su clase y que tendrá un servicio que es una instancia única (es decir, los proterties clase siguen siendo los mismos) y permite múltiples conexiones simultáneas.

Ahora tiene que cuidar de su propiedad de lectura/escritura, es decir, utilizar bloqueos como ya lo ha hecho (o alguna otra técnica).

+3

Respuesta repetida –