在控制台应用程序C#中实现单例的最佳方法?

在控制台应用程序C#中实现单例的最佳方法?,c#,.net-3.5,singleton,C#,.net 3.5,Singleton,我有一个基于服务器的控制台应用程序。我只希望为特定服务器一次运行一个实例(这与运行它的用户无关) 我需要添加一个检查以确保只有一个实例正在运行,我已经可以通过检查服务器上正在运行的进程来做到这一点,但这是最佳实践吗 由于我一直在寻找改进编码风格和保持最新的方法,最近有更好的方法吗?如果您在想——“如果它没有坏,就不要修复它”,也许您是对的,但我想更多地利用框架内置的功能 我使用的是.NETV3.5,这是一个控制台应用程序 提前感谢您应该使用互斥类,就像这里解释的那样:有一些方法可以做到这一点,包

我有一个基于服务器的控制台应用程序。我只希望为特定服务器一次运行一个实例(这与运行它的用户无关)

我需要添加一个检查以确保只有一个实例正在运行,我已经可以通过检查服务器上正在运行的进程来做到这一点,但这是最佳实践吗

由于我一直在寻找改进编码风格和保持最新的方法,最近有更好的方法吗?如果您在想——“如果它没有坏,就不要修复它”,也许您是对的,但我想更多地利用框架内置的功能

我使用的是.NETV3.5,这是一个控制台应用程序


提前感谢

您应该使用互斥类,就像这里解释的那样:

有一些方法可以做到这一点,包括上面提到的文章

从各地收集了大量汇编代码,但我最终找到了神奇的酱汁,它在概念上创建了一个单例控制台应用程序,该应用程序还可以继续接收命令行参数。因此,第一次运行时,它会处理其命令行参数,然后等待。当您再次尝试运行此操作时,如果第一个进程仍在运行,则这些命令行参数将传递给第一个进程进行处理,而第二个进程将终止

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();
                        }
                    }
                }
            }
        }
    }
}
使用系统;
使用System.IO;
使用System.IO.Pipes;
使用系统线程;
使用System.Threading.Tasks;
名称空间SingletonConsoleApp
{
班级计划
{
const string InterprocessID=“{D2D6725E-79C3-4988-8475-4446549B6E6D}”//可以是唯一的任何内容
静态互斥体appSingletonMaker=新互斥体(true,进程间id);
静态void Main(字符串[]参数)
{
if(appSingletonMaker.WaitOne(TimeSpan.Zero,true))
{
var argHandler=新操作((参数=>
{
WriteLine(String.Join(“,参数));
}));
Task.Run(()=>
{
使用(var服务器=新名称PipeServerStream(进程间ID))
{
使用(变量读取器=新的StreamReader(服务器))
{
使用(var writer=newstreamwriter(服务器))
{
while(true)
{
WaitForConnection();
var incomingArgs=reader.ReadLine().Split('\t');
作者:WriteLine(“完成”);
writer.Flush();
server.Disconnect();
argHandler(incomingArgs);
}
}
}
}
});
argHandler(args);
Console.ReadKey();
appSingletonMaker.ReleaseMutex();
}
其他的
{
如果(args.Length>0)
{
使用(var client=newnamedpipeclientstream(进程间ID))
{
client.Connect();
var writer=新的StreamWriter(客户端);
使用(变量读取器=新的StreamReader(客户端))
{
writer.WriteLine(String.Join(“\t”,args));
writer.Flush();
reader.ReadLine();
}
}
}
}
}
}
}

+1和已接受的答案,不确定您是否能得到比此更好的答案。太好了!这花了整整2分钟来实现:)我想补充一点,我注意到互斥体有一个guid,这是否意味着如果一个顽固的管理员重命名正在执行的exe,它仍然不会运行,因为互斥体guid在两个应用程序中都是相同的,即使是重命名的应用程序也一样?这基本上只是一个字符串标识码,它可以是guid,也可以是项目的原始全名,或者其他任何东西,它必须是唯一的,这样您就不会与其他应用程序发生冲突。