C#中仅运行一个程序实例的方法

在日常工作中,大家经常会遇到想要让程序同时只能有一个实例在内存中运行的情况。比如某些比较耗费资源的工具,或者占用了某些特定端口的程序,启动多个实例没有意义。那么我们是怎么实现这种限制的呢?

在C#中,一般我们有两种办法,都非常简单。

  • 使用Mutex

在C#中有两种Mutex,一种是Local的,仅在创建的进程中可见,主要作用就是实现进程内线程之间的同步。还有一种是有名字的,也叫Global Mutex,在进程间可见,我们今天要使用的就是它。

static void Main(string[] args)
       {
           bool createdNew;
           var mutex = new Mutex(true, "OnlyOneRunning", out createdNew);
           if(!createdNew)
           {
               Console.WriteLine("Only a single instance can run in a time");
               return;
           }
           else
           {
               mutex.ReleaseMutex();
               Thread.Sleep(5000);
           }
       }

注意看,我们在构造Mutex的时候给了它一个名字,这样它就是全局Mutex,可以在不同的进程间可见。
我们在构造Mutex的时候,会看看是否已经有这个名字的Mutex存在,如果有,后面那个bool就是false,反之为true。这就是我们判断内存中是否已经有这个程序的实例运行的依据。运行看试试。
在这里插入图片描述
不错,只要内存中有这个程序的进程在运行,再次企图运行这个进程,就会直接退出。
不过使用这个方法的时候要注意Mutex的命名,不要和其他程序共用,否则会出现误判的问题。建议使用程序集名字以减少无意间和其他程序共用Mutex名字的几率。
 

  • 使用Process类
static void Main(string[] args)
        {            
            if (Process.GetProcesses().Count(
                p => p.ProcessName.ToLower() == 
                Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.SetupInformation.ApplicationName.ToLower())
                ) > 1)
            {
                Console.WriteLine("Only a single instance can run in a time");
                return;
            }
            Thread.Sleep(5000);
        }

在这个方法中,使用进程来查看是否已经有本程序运行,如果有,则返回。通过判断当前应用程序域的启动程序的名字是否在进程中存在多个从而得出是否已经有本程序运行。
 

  • 其他的方法
    除了上面提到的两个方法之外,还有其他的一些方法比如:
    • 写注册表,在程序启动的时候检查并写注册表,程序退出之前恢复注册表。
    • 建立标记位,创建空文件在某个特定目录以表明程序启动,原理和写注册表相同。

总体来说,用的最多的还是前两种办法,因为它们不会修改注册表或者创建文件,没有任何side effect。

猜你喜欢

转载自blog.csdn.net/deatharthas/article/details/102877632