我有一个基于服务器的控制台应用程序。我只希望为特定服务器一次运行一个实例(这与可能正在运行它的用户无关)。
我需要添加一个检查以确保只有一个实例正在运行,我已经可以通过检查服务器上正在运行的进程来执行此操作,但这是最佳做法吗?
由于我一直在寻找改进编码风格和保持最新的方法,最近有更好的方法吗?如果您正在考虑 - “如果它没有破坏就不要修复它”,也许您是对的,但我想更多地利用内置功能的框架。
我使用的是.net v3.5,这是一个控制台应用程序。
提前致谢
答案 0 :(得分:14)
您应该使用Mutex类,如下所述:C# .NET Single Instance Application
答案 1 :(得分:3)
从各处获得了大量的代码和代码,但我终于找到了从概念上创建一个单独的控制台应用程序的魔法酱,它也可以继续接收命令行参数。所以第一次运行时,它会处理命令行参数,然后等待。当你再次尝试运行它时,如果第一个仍在运行,那么这些命令行参数将被传递给第一个进程进行处理,第二个进程就会死掉。
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 :(得分:2)
What is the correct way to create a single instance application有一些方法可以做到这一点,包括上面提到的文章
答案 3 :(得分:0)