zoukankan      html  css  js  c++  java
  • 保证一个程序只运行一次

    先讲实现方法:  
      首先依然是命名空间:  
              using   System.Threading;  
      然后修改  
      static   void   Main()    
          {  
            bool   bCreatedNew;  
       
            Mutex   ltt   =new   Mutex(   false,   "myUniqueName",   out   bCreatedNew   );  
       
            if(   bCreatedNew   )  
       
                      Application.Run(new   Form1());  
          }  
      接下来,说一下原理:  
      当两个或更多线程需要同时访问一个共享资源时,系统需要使用同步机制来确保一次只有一个线程使用该资源。Mutex   是同步基元,它只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。  
      相信如果学过操作系统的朋友一定能够看的懂.  
      可以使用   WaitHandle.WaitOne   请求互斥体的所属权。拥有互斥体的线程可以在对   Wait   的重复调用中请求相同的互斥体而不会阻塞其执行。但线程必须调用   ReleaseMutex   方法同样多的次数以释放互斥体的所属权。如果线程在拥有互斥体期间正常终止,则互斥体状态设置为终止,并且下一个等待线程获得所属权。如果没有线程拥有互斥体,则互斥体状态为终止。


    方法一:使用Mutex来进行
        1. 首先要添加如下的namespace:
           using System.Threading;
    2. 修改系统Main函数,大致如下:
                    bool bCreatedNew;
                    //Create a new mutex using specific mutex name
                    Mutex m =new Mutex( false, "myUniqueName", out bCreatedNew );
                   if( bCreatedNew )
                   Application.Run(new yourFormName());
    如上面编码就可以了,要注意的一点是,在给Mutex起名字的时候,不要太简单,以防止和其他程序的Mutex重复,从而达不到所预想的效果。
    方法二:使用Process来进行
    1. 首先要添加如下的namespace:
    using System.Diagnostics;
    using System.Reflection;
    2. 添加如下函数:
            public static Process RunningInstance()
            {
                Process current = Process.GetCurrentProcess();
                Process[] processes = Process.GetProcessesByName(current.ProcessName);
                //Loop through the running processes in with the same name
                foreach (Process process in processes)
                {
                    //Ignore the current process
                    if (process.Id != current.Id)
                    {
                        //Make sure that the process is running from the exe file.
                        if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName)
                        {
                            //Return the other process instance.
                            return process;
                        }
                    }
                }
                //No other instance was found, return null.
                return null;
            }
    3. 修改系统Main函数,大致如下:
                if( RunningInstance() == null )
                    Application.Run(new yourFormName());
    如上面编码就可以了,要注意的一点是,在判断进程模块文件名是否相等这部分的代码,是可选的。如果当前的程序在文件系统中只存在一个的话,以上的方法是可以的;否则不要删除这部分的代码。
    对比两种方法,就效率和简便性来说,前一种方法是最好的,也是我比较喜欢的;后一种方法,速度比较慢,其次通过ProcessName去系统中查寻,有可能查出来的Process并不是我想要得,虽说在后面加了文件目录判断,但是其含有潜在的问题(前面已经说出来)。不过,第一种方法也有缺陷,就是扩展性操作不方便,例如:让程序只运行一次,如果程序已经运行,把它弹出并显示到最前面。对于此,后一种方法就很有优势了。
  • 相关阅读:
    MySql 用户 及权限操作
    MAC 重置MySQL root 密码
    在mac系统安装Apache Tomcat的详细步骤[转]
    Maven:mirror和repository 区别
    ES6 入门系列
    转场动画CALayer (Transition)
    OC 异常处理
    Foundation 框架
    Enum枚举
    Invalid App Store Icon. The App Store Icon in the asset catalog in 'xxx.app' can’t be transparent nor contain an alpha channel.
  • 原文地址:https://www.cnblogs.com/ywolf123/p/1190630.html
Copyright © 2011-2022 走看看