10
votes

Meilleure façon de mettre en œuvre singleton dans une demande de console C #?

J'ai une application de console qui est basée sur le serveur. Je veux seulement 1 instance de fonctionnement à la fois pour un serveur particulier (c'est-à-dire quel que soit l'utilisateur qui pourrait l'exécuter).

Je dois ajouter un chèque pour vous assurer que 1 instance de celui-ci est en cours d'exécution, je peux déjà le faire en cochant les processus d'exécution sur le serveur, mais est cette meilleure pratique?

Puisque je cherche constamment des moyens d'améliorer les styles de codage et de rester à jour, y a-t-il une meilleure façon de le faire ces derniers temps? Si vous pensez - "si ce n'est pas cassé ne le répare pas", vous avez peut-être raison, mais je veux prendre plus d'avantage du cadre intégré dans la fonctionnalité.

J'utilise .NET V3.5, et c'est une application de console.

Merci d'avance


0 commentaires

4 Réponses :


14
votes

Vous devriez utiliser la classe Mutex, comme expliqué ici: C # .NET Application instance unique


4 commentaires

+1 et réponse acceptée, pas sûr si vous pouvez obtenir une meilleure réponse que cela. Tyvm!


Bien cela a pris 2 minutes entière pour mettre en œuvre :)


Une chose que j'aimerais ajouter, je remarque que le mutex a un GUID, cela signifie-t-il que si un administrateur obstiné renomme l'exécution exe, il ne fonctionne toujours pas parce que le GUID Mutex est le même dans les deux applications, même le renommé qu'un?


C'est fondamentalement juste un code d'identification de chaîne que vous choisissez, il peut s'agir d'un GUID, ou du nom complet d'origine de votre projet, ou peu importe, il doit simplement être unique pour que vous ne puissiez pas entrer en collision avec d'autres applications.



2
votes

Quelle est la bonne façon de créer Une seule demande d'instance a des moyens de le faire, y compris l'article mentionné ci-dessus


0 commentaires


4
votes

a pris beaucoup d'assemblage de morceaux de code de partout, mais j'ai enfin trouvé la sauce magique qui crée conceptuellement une application Singleton Console qui peut également continuer à recevoir des arguments de ligne de commande. Donc, la première fois que cela est couru, il traite ses paramètres de ligne de commande puis attend. Lorsque vous essayez de l'exécuter à nouveau, si le premier tourne toujours, ces arguments de ligne de commande sont transmis au premier processus de manipulation et le second processus meurt.

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


0 commentaires