2009-06-24 14 views
11

Sto creando un framework hardware .net personalizzato che verrà utilizzato da altri programmatori per controllare alcuni componenti hardware. Aggiungeranno un riferimento alla nostra DLL per arrivare al nostro framework hardware. Ho bisogno di una classe condivisa a cui accedere da più applicazioni (processi).È possibile condividere una classe Singleton in una DLL tra i processi?

Il modello singleton sembra essere quello di cui ho bisogno ma funziona solo per più thread all'interno del processo. Potrei sbagliare completamente ma qui c'è un esempio del codice C# che ho attualmente. Non posso fare a meno di pensare che il design sia scorretto. Vorrei poter condividere informazioni più specifiche ma non posso.

  • Devo sottolineare che non avrò alcun controllo sull'applicazione del cliente. La soluzione deve essere contenuta all'interno della struttura (DLL) stessa.

Il quadro: (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; 
     } 
    } 
} 

l'applicazione di test: (eventualmente cliente app)

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 prima applicazione lanciata dà una potenza di:

Premi enter per acquisire la risorsa!

1: 2009/06/24 08:27:34

3: 2009/06/24 08:27:34

premere INVIO per chiudere il processo!

La seconda applicazione dà una potenza di:

Premere Invio per catturare la risorsa!

9: 2009/06/24 08:27:35

10: 2009/06/24 08:27:35

premere INVIO per chiudere il processo!

Conclusione:

vorrei vedere entrambe le applicazioni restituiscono la stessa stringa del tempo della prima istanza della classe.

Come si può vedere il singleton funziona per il thread multiplo all'interno del processo ma non i processi incrociati. Forse questo non può essere fatto perché non riesco a trovare alcuna soluzione.

+0

devo sottolineare che lo farò non ha alcun controllo sull'applicazione del cliente. La soluzione deve essere contenuta all'interno della struttura (DLL) stessa. –

risposta

2

Non è possibile utilizzare un singleton per la sincronizzazione tra le applicazioni. Ciascuno viene eseguito nel proprio spazio applicativo e, per motivi di sicurezza, non può accedere alla memoria/agli oggetti/ecc. dall'altra senza un metodo di comunicazione (come il remoting) Per sincronizzare i due dovrebbero essere remoti in un terzo programma.

+0

Ho avuto la stessa domanda, ma come alternativa, non posso posizionare questa istanza singleton in GAC ed entrambi i processi possono fare riferimento a tale istanza? In questo modo, se aggiorno l'oggetto da un processo, l'altro processo non otterrà l'istanza aggiornata? O ogni processo carica l'istanza nel proprio processo? – hangar18

+0

@ hangar18 è esattamente la stessa domanda: posizionarlo in GAC non fa niente di speciale, è ancora una DLL! – markmnl

7

Sì, è possibile condividere un singleton tra diversi processi. Tuttavia, per ottenere questo risultato è necessario avvalersi di una tecnologia che supporta la comunicazione tra processi.

Le tecnologie più diffuse che ti consentono di condividere il tuo oggetto in modo abbastanza diretto sono Remoting e WCF.

Fare un esempio di condivisione di un singleton con uno di questi è oltre lo scopo di una risposta SO. Ma ci sono molti tutorial sul web per ognuno di questi. Googling o tecnologia più singleton dovrebbe metterti sulla giusta strada.

2

Per aggiungere alla risposta di Kevin, il tuo costruttore per la tua classe Le risorse dovrebbero essere rese private per essere un vero singleton, altrimenti nulla impedisce a qualcuno di creare una nuova istanza della classe Risorse attraverso il costruttore. Questo non risolve il tuo problema, ma impedisce il cattivo utilizzo di Singleton.

+0

Si è corretti sul fatto che il costruttore sia privato. Ho risolto il campione. –

+0

Questo è solo un esempio. Non sto cercando di condividere una data. Sto cercando di controllare una risorsa hardware. –

+0

Un file in questo caso non andrà bene. Errore mio. – AlbertoPL

1

Basta chiamare una proprietà singleton in un assembly diverso da due processi diversi per creare diverse istanze di tale classe.

Ma è possibile condividere facilmente le informazioni tra i processi utilizzando .Net Remoting oppure eseguire eventi di interprocesso se è necessaria solo una semplice segnalazione (EventWaitHandle).

[Edit:] per farlo sembrare come un Singleton per i chiamanti, è possibile esporre una classe che internamente utilizzare Remoting istanziare un Singleton, e quindi restituire l'istanza in modo trasparente. Ecco un esempio che (penso) lo fa: http://www.codeproject.com/KB/dotnet/remotingsingleton.aspx

Problemi correlati