Pregunta

Estoy creando un marco de hardware .net personalizado que será utilizado por otros programadores para controlar parte del hardware. Agregarán una referencia a nuestra DLL para llegar a nuestro marco de hardware. Necesito una clase compartida a la que se pueda acceder desde múltiples aplicaciones (procesos).

El patrón singleton parece ser lo que necesito pero solo funciona para múltiples hilos 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 enfatizar que no tendré control sobre la aplicación del cliente. La solución debe estar contenida dentro del marco (DLL) en sí.

El marco: (DLL compartida)

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: (eventualmente la aplicación del 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 lanzada da una salida de:

  

¡Presione enter para capturar el recurso!

     

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

     

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

     

¡Presione enter para cerrar el proceso!

La segunda aplicación da una salida de:

  

¡Presione enter para capturar el recurso!

     

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

     

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

     

¡Presione enter para cerrar el proceso!

Conclusión :

Me gustaría ver que ambas aplicaciones devuelvan la misma cadena de tiempo de la primera instanciación de la clase.

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

¿Fue útil?

Solución

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

Otros consejos

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

Las tecnologías más populares que le permiten compartir su objeto de forma 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 cualquier tecnología más singleton debería ponerlo en el camino correcto.

Para agregar a la respuesta de Kevin, su constructor para los recursos de su clase realmente debe hacerse privado para que sea un verdadero singleton, 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 use indebidamente el Singleton.

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

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

[Editar:] Para que parezca un Singleton para sus llamantes, puede exponer una clase que utilizará Remoting internamente para crear una instancia de 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

Hay formas de hacerlo como se mencionó anteriormente. Pero es torpe si usa WCF o remoting. Intente técnicas de sincronización de subprocesos entre procesos.

Para obtener más información, lea el libro electrónico gratuito en línea sobre subprocesos

http://www.albahari.com/threading/

Vea especialmente las construcciones de sincronización de procesos cruzados aquí ...

http://www.albahari.com/threading/part2.aspx#_Synchronization_Essentials

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top