2009-06-24 10 views
11

Tworzę niestandardową platformę sprzętową .net, która będzie używana przez innych programistów do kontrolowania niektórych urządzeń. Dodadzą odnośnik do naszej biblioteki DLL, aby uzyskać dostęp do naszej platformy sprzętowej. Potrzebuję udostępnionej klasy, do której dostęp będzie uzyskiwany z wielu aplikacji (procesów).Czy klasa Singleton wewnątrz DLL może być współdzielona pomiędzy procesami?

Wygląda na to, że wzór singletonowy jest tym, czego potrzebuję, ale działa tylko w przypadku wielu wątków w procesie. Mogę być całkowicie błędny, ale tutaj jest przykład kodu C#, który obecnie mam. Nie mogę oprzeć się wrażeniu, że projekt jest nieprawidłowy. Chciałbym podzielić się bardziej szczegółowymi informacjami, ale nie mogę.

  • Muszę podkreślić, że nie będę mieć żadnej kontroli nad aplikacją klienta. Rozwiązanie musi być zawarte wewnątrz samej struktury (DLL).

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

Application Test: (ostatecznie app klient)

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); 
    } 
} 

Pierwsza rozpoczęła aplikacja daje moc:

Naciśnij klawisz Enter, aby przechwycić zasób!

1: 24.06.2009 08:27:34

3: 24.06.2009 08:27:34

Naciśnij ENTER, aby zamknąć proces!

Druga aplikacja daje moc:

enter aby przechwytywać zasobu!

9: 24.06.2009 08:27:35

10: 24.06.2009 08:27:35

Naciśnij ENTER, aby zamknąć proces!

Wnioski:

Chciałbym zobaczyć obie aplikacje zwracają ten sam ciąg czasów pierwszej instancji klasy.

Jak widać singleton działa dla wielu wątków w procesie, ale nie krzyżuje procesów. Może nie można tego zrobić, bo nie mogę znaleźć rozwiązania.

+0

Muszę podkreślić, że będę nie kontrolujemy aplikacji klienta. Rozwiązanie musi być zawarte wewnątrz samej struktury (DLL). –

Odpowiedz

2

Nie można używać pojedynczego singleta do synchronizacji między aplikacjami. Każdy działa we własnej przestrzeni aplikacji, a ze względów bezpieczeństwa nie może uzyskać dostępu do pamięci/obiektów/etc. z drugiej bez metody komunikacji (np. zdalna) Aby zsynchronizować te dwie, musielibyśmy zdalnie przejść do trzeciego programu.

+0

Miałem to samo pytanie, ale jako alternatywa, nie mogę umieścić tej pojedynczej instancji w GAC i oba procesy mogą odwoływać się do tej instancji? W ten sposób, jeśli zaktualizuję obiekt z jednego procesu, to czy drugi proces nie otrzyma zaktualizowanej instancji? LUB czy każdy proces ładuje instancję w swoim procesie? – hangar18

+0

@ hangar18 to dokładnie to samo pytanie - umieszczenie go w GAC nie robi nic specjalnego, to wciąż jest dll! – markmnl

7

Tak, możliwe jest udostępnienie pojedynczego ciągu kilku procesów. Będziesz jednak musiał skorzystać z technologii wspierającej komunikację międzyprocesową, aby osiągnąć ten wynik.

Najpopularniejszymi technologiami, które umożliwiają bezpośrednie udostępnianie obiektu, są usługi Remoting i WCF.

Podanie przykładu udostępniania singleton z jednym z nich wykracza poza zakres odpowiedzi WR. Ale w Internecie jest wiele samouczków dla każdego z nich. Googling, technologia plus singleton, powinien postawić cię na dobrej drodze.

2

Aby dodać do odpowiedzi Kevina, twój konstruktor dla twojej klasy Zasoby powinny być naprawdę prywatne, aby było prawdziwym singletonem, w przeciwnym razie nic nie powstrzyma kogoś przed stworzeniem nowej instancji klasy Zasoby przez konstruktora. To nie rozwiązuje twojego problemu, ale powstrzymuje go od nadużywania Singleton.

+0

Masz rację, że konstruktor jest prywatny. Naprawiłem próbkę. –

+0

To tylko przykład. Nie próbuję udostępnić daty. Próbuję kontrolować zasoby sprzętowe. –

+0

Plik w tym przypadku nie będzie dobry. Mój błąd. – AlbertoPL

1

Po prostu wywołanie właściwości singleton w innym złożeniu z dwóch różnych procesów spowoduje utworzenie różnych instancji tej klasy.

Ale można łatwo udostępniać informacje między procesami za pomocą .Net Remoting lub wywoływać zdarzenia międzyprocesowe, jeśli potrzebujesz tylko prostej sygnalizacji (EventWaitHandle).

[Edit:], aby wyglądał jak Singleton do swoich rozmówców, można narazić klasy, która będzie wewnętrznie korzystania Remoting do instancji singleton, a następnie powrócić instancję przejrzysty. Oto przykład, który (jak sądzę) robi: http://www.codeproject.com/KB/dotnet/remotingsingleton.aspx

Powiązane problemy