2009-12-04 17 views
8

Tengo una aplicación de consola basada en servidor. Solo quiero que se ejecute una instancia de una vez para un servidor en particular (esto es independientemente del usuario que pueda ejecutarlo).¿La mejor manera de implementar singleton en una aplicación de consola C#?

Necesito agregar una verificación para asegurarme de que solo se está ejecutando 1 instancia, puedo hacerlo comprobando los procesos en ejecución en el servidor, pero ¿es esta la mejor práctica?

Como siempre estoy buscando formas de mejorar los estilos de codificación y estar al día, ¿hay alguna forma mejor de hacerlo últimamente? Si estás pensando: "Si no está roto, no lo arregles". Quizás tengas razón, pero quiero aprovechar más la funcionalidad integrada del framework.

Estoy usando .net v3.5, y esta es una aplicación de consola.

Gracias de antemano

Respuesta

14

Debe utilizar la clase objeto mutex, como se explica aquí: C# .NET Single Instance Application

+0

+1 y la respuesta es aceptada, no estoy seguro si puede obtener una mejor respuesta que esta. ¡tyvm! –

+0

+1 Estoy de acuerdo con JL –

+0

Bueno, eso tomó un total de 2 minutos para implementar :) –

1

Tomó una gran cantidad de fragmentos de códigos ensamblados de todas partes, pero finalmente encontré la salsa mágica que conceptualmente crea una aplicación de consola singleton que también puede continuar recibiendo comandos argumentos de línea Entonces, la primera vez que se ejecuta esto, procesa sus parámetros de línea de comando y luego espera. Cuando intente ejecutar esto de nuevo, si el primero todavía se está ejecutando, los argumentos de la línea de comando se pasan al primer proceso para su manejo, y el segundo proceso muere.

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(); 
         } 
        } 
       } 
      } 
     } 
    } 
} 
Cuestiones relacionadas