2009-12-04 55 views
8

我有一個基於服務器的控制檯應用程序。我只需要一次爲特定服務器運行它的一個實例(不管可能正在運行它的用戶)。在控制檯應用程序C#中實現單例的最佳方法?

我需要添加一個檢查以確保它只有一個實例正在運行,我可以通過檢查服務器上正在運行的進程來做到這一點,但這是否是最佳做法?

因爲我一直在尋找方法來改進編碼風格並保持最新,有沒有更好的方法來做到這一點?如果你在思考 - 「如果沒有破解,不要修復它」,也許你是對的,但我想更多地利用框架內置的功能。

我使用.net v3.5,這是一個控制檯應用程序。

在此先感謝

回答

14

您應該使用Mutex類,像這裏解釋:C# .NET Single Instance Application

+0

+1和接受的答案,不知道如果你能得到比這更好的答案。 tyvm! –

+0

+1我同意JL –

+0

嗯,整個2分鐘實施:) –

1

拿了很多來自任何地方的代碼組裝,但我終於找到了魔法醬,它在概念上創建了一個單一控制檯應用程序,它也可以繼續接收命令線參數。所以第一次運行時,它會處理它的命令行參數,然後等待。當您嘗試再次運行此操作時,如果第一個仍在運行,那些命令行參數將傳遞給第一個進程以進行處理,第二個進程將死亡。

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(); 
         } 
        } 
       } 
      } 
     } 
    } 
} 
相關問題