2009-12-04 14 views
8

Mam aplikację konsolową opartą na serwerze. Chcę tylko 1 wystąpienie go uruchomionego na raz dla konkretnego serwera (jest to niezależne od użytkownika, który może go uruchamiać).Najlepszy sposób na implementację singletona w aplikacji konsolowej C#?

Potrzebuję dodać czek, aby upewnić się, że tylko 1 wystąpienie jest uruchomione, mogę już to zrobić, sprawdzając działające procesy na serwerze, ale czy jest to najlepsza praktyka?

Ponieważ stale szukam sposobów na poprawę stylów kodowania i bycie na bieżąco, czy istnieje lepszy sposób na zrobienie tego w ostatnim czasie? Jeśli myślisz: "Jeśli to nie jest zepsute, nie naprawiaj tego", Może masz rację, ale chcę skorzystać z wbudowanej funkcji ramowej.

Używam .net v3.5, a to jest aplikacja konsoli.

góry dzięki

Odpowiedz

14

Należy użyć klasy mutex, jak wyjaśniono tutaj: C# .NET Single Instance Application

+0

+1 i zaakceptowana odpowiedź, nie wiem, czy można uzyskać lepszą odpowiedź. tyvm! –

+0

+1 Zgadzam się z JL –

+0

Cóż, zajęło mi to całe 2 minuty :) –

1

wziął dużo elementów i kawałków kodu zewsząd, ale w końcu znalazłem magiczny sos, który koncepcyjnie tworzy pojedynczą aplikację konsolową, która może również nadal otrzymywać polecenia argumenty liniowe. Tak więc po raz pierwszy jest uruchamiany, przetwarza swoje parametry wiersza polecenia, a następnie czeka. Kiedy spróbujesz uruchomić to ponownie, jeśli pierwszy jest nadal uruchomiony, te argumenty wiersza poleceń są przekazywane do pierwszego procesu obsługi, a drugi proces umiera.

using System; 
using System.IO; 
using System.IO.Pipes; 
using System.Threading; 
using System.Threading.Tasks; 

namespace SingletonConsoleApp 
{ 
    class Program 
    { 
     const string InterprocessID = "{D2D6725E-79C3-4988-8475-4446549B6E6D}"; // can be anything that's unique 
     static Mutex appSingletonMaker = new Mutex(true, InterprocessID); 

     static void Main(string[] args) 
     { 
      if (appSingletonMaker.WaitOne(TimeSpan.Zero, true)) 
      { 
       var argHandler = new Action<string[]>((arguments => 
       { 
        Console.WriteLine(String.Join(" ", arguments)); 
       })); 
       Task.Run(() => 
       { 
        using (var server = new NamedPipeServerStream(InterprocessID)) 
        { 
         using (var reader = new StreamReader(server)) 
         { 
          using (var writer = new StreamWriter(server)) 
          { 
           while (true) 
           { 
            server.WaitForConnection(); 
            var incomingArgs = reader.ReadLine().Split('\t'); 
            writer.WriteLine("done"); 
            writer.Flush(); 
            server.Disconnect(); 
            argHandler(incomingArgs); 
           } 
          } 
         } 
        } 
       }); 
       argHandler(args); 
       Console.ReadKey(); 
       appSingletonMaker.ReleaseMutex(); 
      } 
      else 
      { 
       if (args.Length > 0) 
       { 
        using (var client = new NamedPipeClientStream(InterprocessID)) 
        { 
         client.Connect(); 
         var writer = new StreamWriter(client); 
         using (var reader = new StreamReader(client)) 
         { 
          writer.WriteLine(String.Join("\t", args)); 
          writer.Flush(); 
          reader.ReadLine(); 
         } 
        } 
       } 
      } 
     } 
    } 
} 
Powiązane problemy