Лучший способ реализовать singleton в консольном приложении C#?
У меня есть консольное приложение на основе сервера. Я хочу, чтобы только 1 экземпляр его работал сразу для определенного сервера (это независимо от пользователя, который может его запускать).
Мне нужно добавить проверку, чтобы убедиться, что работает только 1 экземпляр, я уже могу сделать это, проверив запущенные процессы на сервере, но это лучшая практика?
поскольку я постоянно ищу способы улучшить стили кодирования и оставаться в курсе, есть ли лучший способ делать это в последнее время? Если вы думаете: "если он не сломан, не исправляйте его", возможно, вы правы, но я хочу использовать больше преимуществ фреймворка, встроенного в функциональность.
Я использую .net v3.5, и это консольное приложение.
спасибо заранее
4 ответов
вы должны использовать класс мьютекса, как описано здесь:C# .NET один экземпляр приложения
каков правильный способ создания одного экземпляра приложения имеет некоторые способы сделать это, включая статью, упомянутую выше
потребовалось много сборки бит и фрагментов кода отовсюду, но я, наконец, нашел волшебный соус, который концептуально создает одноэлементное консольное приложение, которое также может продолжать получать аргументы командной строки. Поэтому при первом запуске он обрабатывает параметры командной строки, а затем ждет. При повторной попытке запустить этот процесс, если первый все еще выполняется, эти аргументы командной строки передаются первому процессу для обработки, а второй процесс умирает.
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();
}
}
}
}
}
}
}