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

Posted

技术标签:

【中文标题】在控制台应用程序 C# 中实现单例的最佳方法?【英文标题】:Best way to implement singleton in a console application C#? 【发布时间】:2009-12-04 12:24:26 【问题描述】:

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

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

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

我正在使用 .net v3.5,这是一个控制台应用程序。

提前致谢

【问题讨论】:

【参考方案1】:

您应该使用 Mutex 类,如下所述:C# .NET Single Instance Application

【讨论】:

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

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

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

【讨论】:

【参考方案3】:

What is the correct way to create a single instance application有一些方法可以做到这一点,包括上面提到的文章

【讨论】:

【参考方案4】:

Check this minimalistic console app project

【讨论】:

以上是关于在控制台应用程序 C# 中实现单例的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中实现单例设计模式? [复制]

在 Node JS 应用程序中实现单例 mongoDB DB 对象

iOSARC-MRC下的单例及其应用

在 Java 中实现单例模式的有效方法是啥? [关闭]

如何使用工厂构造函数在 Dart 中实现单例模式?

线程安全在Java中实现单例模式的有效方法? [复制]