2009-06-24 8 views
11

Estoy creando un framework de hardware .net personalizado que será utilizado por otros programadores para controlar algunos hardware. Agregarán una referencia a nuestra DLL para acceder a nuestro marco de hardware. Necesito una clase compartida a la que se accederá desde múltiples aplicaciones (procesos).¿Se puede compartir una clase Singleton dentro de una DLL en todos los procesos?

El patrón singleton parece ser lo que necesito pero solo funciona para varios subprocesos dentro de su proceso. Podría estar completamente equivocado, pero aquí hay un ejemplo del código C# que tengo actualmente. No puedo evitar sentir que el diseño es incorrecto. Desearía poder compartir información más específica, pero no puedo.

  • Debo recalcar que no tendré control sobre la aplicación del cliente. La solución debe estar contenida dentro del marco (DLL).

El Marco de: (Shared DLL)

public class Resources 
{ 
    static readonly Resources m_instance = new Resources(); 

    public string Data; 

    private Resources() 
    { 
     Data = DateTime.Now.ToString(); 
    } 

    public static Resources Instance 
    { 
     get 
     { 
      return m_instance; 
     } 
    } 
} 

la aplicación de prueba: (eventual aplicación cliente)

class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine("Press enter to capture the resource!"); 
     Console.ReadLine(); 

     var resources = Resources.Instance; 
     Console.WriteLine("\r\n{0}: {1}\r\n", Thread.CurrentThread.ManagedThreadId, resources.Data); 

     BackgroundWorker worker = new BackgroundWorker(); 
     worker.DoWork += WorkerDoWork; 
     worker.RunWorkerAsync(); 

     while (worker.IsBusy) 
     { 
      Thread.Sleep(100); 
     } 

     Console.WriteLine("Press enter to close the process!"); 
     Console.ReadLine(); 
    } 

    static void WorkerDoWork(object sender, DoWorkEventArgs e) 
    { 
     var resources = Resources.Instance; 
     Console.WriteLine("\r\n{0}: {1}\r\n", Thread.CurrentThread.ManagedThreadId, resources.Data); 
    } 
} 

La primera aplicación iniciada da una salida de:

¡Presione enter para capturar el recurso!

1: 6/24/2009 8:27:34 AM

3: 6/24/2009 8:27:34 AM

presione ENTRAR para cerrar el proceso!

La segunda aplicación da una potencia de:

Pulse Intro para capturar el recurso!

9: 6/24/2009 8:27:35 AM

10: 6/24/2009 8:27:35 AM

presione ENTRAR para cerrar el proceso!

Conclusión:

me gustaría ver las dos solicitudes de restitución de la misma cadena del tiempo de la primera instancia de la clase.

Como puede ver, el singleton funciona para el hilo múltiple dentro del proceso, pero no para los procesos cruzados. Tal vez esto no se puede hacer porque no puedo encontrar ninguna solución.

+0

Debo subrayar que lo haré no tiene control sobre la aplicación del cliente. La solución debe estar contenida dentro del marco (DLL). –

Respuesta

2

No puede usar un singleton para sincronizar entre aplicaciones. Cada uno se ejecuta en su propio espacio de aplicación, y como una cuestión de seguridad no puede acceder a la memoria/objetos/etc. del otro sin un método de comunicación (como la comunicación remota) Para sincronizar los dos tendrían que pasar a un tercer programa.

+0

Tuve la misma pregunta, pero como alternativa, ¿no puedo colocar esta instancia singleton en GAC y ambos procesos pueden referirse a esa instancia? De esta forma, si actualizo el objeto de un proceso, ¿no recibiría el otro proceso la instancia actualizada? O ¿cada proceso carga la instancia en su propio proceso? – hangar18

+0

@ hangar18 esa es exactamente la misma pregunta: colocarlo en GAC no hace nada especial, ¡sigue siendo un dll! – markmnl

7

Sí, es posible compartir un singleton entre varios procesos. Sin embargo, deberá aprovechar una tecnología que admite la comunicación entre procesos para lograr este resultado.

Las tecnologías más populares que le permiten compartir su objeto de manera bastante directa son Remoting y WCF.

Dar un ejemplo de compartir un singleton con cualquiera de estos está más allá del alcance de una respuesta SO. Pero hay muchos tutoriales en la web para cada uno de estos. Buscar en Google ya sea la tecnología más singleton debería ponerlo en el camino correcto.

2

Para agregar a la respuesta de Kevin, su constructor para su clase Recursos realmente debería hacerse privado para que sea un singleton verdadero, de lo contrario nada impide que alguien cree una nueva instancia de la clase Resources a través del constructor. Esto no resuelve su problema, pero evita que uno abuse de Singleton.

+0

Tiene razón acerca de que el constructor es privado. Arreglé la muestra –

+0

Esto es solo un ejemplo. No estoy tratando de compartir una cita. Estoy tratando de controlar un recurso de hardware. –

+0

Un archivo en ese caso no será bueno. Mi error. – AlbertoPL

1

Simplemente llamando a una propiedad singleton en un ensamblaje diferente de dos procesos diferentes creará instancias diferentes de esa clase.

Pero puede compartir fácilmente información entre procesos usando .Net Remoting, o disparar eventos interproceso si solo necesita señalización simple (EventWaitHandle).

[Editar:] Para que se parezca a un Singleton a sus interlocutores, puede exponer una clase que internamente utilizará Remoting para instanciar un singleton, y luego devolver la instancia de forma transparente. Aquí hay un ejemplo que (creo) hace eso: http://www.codeproject.com/KB/dotnet/remotingsingleton.aspx

Cuestiones relacionadas