Лучший способ реализовать синглтон в консольном приложении C #? - PullRequest
9 голосов
/ 04 декабря 2009

У меня есть консольное приложение, основанное на сервере. Я хочу, чтобы только один экземпляр был запущен одновременно для конкретного сервера (независимо от того, кто его запускал).

Мне нужно добавить проверку, чтобы убедиться, что работает только 1 ее экземпляр, я уже могу это сделать, проверив запущенные процессы на сервере, но лучше ли это?

Поскольку я постоянно ищу способы улучшить стили кодирования и оставаться в курсе, есть ли лучший способ сделать это в последнее время? Если вы думаете: «Если ничего не сломано, то не исправляйте», возможно, вы правы, но я хочу воспользоваться преимуществами встроенной функциональности фреймворка.

Я использую .net v3.5, и это консольное приложение.

Заранее спасибо

Ответы [ 4 ]

14 голосов
/ 04 декабря 2009

Вы должны использовать класс Mutex, как описано здесь: C # .NET Single Instance Application

3 голосов
/ 29 июня 2017

Потребовалось много сборок кусочков кода повсюду, но я наконец нашел волшебный соус, который концептуально создает одноэлементное консольное приложение, которое также может продолжать получать аргументы командной строки. Поэтому при первом запуске он обрабатывает свои параметры командной строки и затем ждет. Когда вы попытаетесь запустить это снова, если первый все еще работает, эти аргументы командной строки передаются первому процессу для обработки, и второй процесс умирает.

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();
                        }
                    }
                }
            }
        }
    }
}
2 голосов
/ 04 декабря 2009

Как правильно создать приложение с одним экземпляром имеет несколько способов сделать это, включая статью, упомянутую выше

0 голосов
...