zoukankan      html  css  js  c++  java
  • 同一个应用程序只开启一个的方法

    关键点——密封类Mutex

    MSDN中Mutex类中是这样解释的:一个同步基元,也可用于进程间同步。其实个人感觉更容易理解的解释是:

    互斥锁(Mutex)

    互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程可以获取它。

    互斥锁可适用于一个共享资源每次只能被一个线程访问的情况。

    如果要获取一个互斥锁。应调用互斥锁上的WaitOne()方法,该方法继承于Thread.WaitHandle类。

    它处于等到状态直至所调用互斥锁可以被获取,因此该方法将组织住主调线程直到指定的互斥锁可用,如果不需要拥有互斥锁,用ReleaseMutex方法释放,从而使互斥锁可以被另外一个线程所获取。

    这是我改自MSDN上的方法(其实也没改多少):

     1 using System;
     2 using System.Threading;
     3 
     4 class Test
     5 {
     6     // Create a new Mutex. The creating thread does not own the
     7     // Mutex.
     8     private static Mutex mut = new Mutex();
     9     static void Main()
    10     {
    11         // Create the threads that will use the protected resource.
    12         for(int i = 0; i < 5; i++)
    13         {
    14             Thread myThread = new Thread(new ThreadStart(MyThreadProc));
    15             myThread.Name = String.Format("Thread{0}", i + 1);
    16             myThread.Start();
    17         }
    18 
    19         // The main thread exits, but the application continues to
    20         // run until all foreground threads have exited.
    21     }
    22 
    23     private static void MyThreadProc()
    24     {
    25           UseResource();
    26     }
    27 
    28     // This method represents a resource that must be synchronized
    29     // so that only one thread at a time can enter.
    30     private static void UseResource()
    31     {
    32         // Wait until it is safe to enter.
    33         mut.WaitOne();
    34 
    35         Console.WriteLine("{0} has entered the protected area", 
    36             Thread.CurrentThread.Name);
    37 
    38         // Place code to access non-reentrant resources here.
    39 
    40         // Simulate some work.
    41         Thread.Sleep(500);
    42 
    43         Console.WriteLine("{0} is leaving the protected area
    ", 
    44             Thread.CurrentThread.Name);
    45          
    46         // Release the Mutex.
    47         mut.ReleaseMutex();
    48     }
    49 }
    View Code

    其实说白了就是:这个坑儿(Mutex mutex)谁蹲下,别个就只能等(mutex.WaitOne();),只有等蹲坑那个人爽完了(mutex.ReleaseMutex();),等待的那个人才能去蹲,然后再让另外的人去等待....

    只开启一个应用程序实现

    在程序的Program.cs里面,先添加如下代码:

    先定义一个互斥锁: Mutex mutexCurrentApp. 

        bool flag = false;  
        mutexCurrentApp = new Mutex(true, Application.ProductName, out flag);  
    个参数:true--给调用线程赋予互斥体的初始所属权  
          //第一个参数:互斥体的名称  
          //第三个参数:返回值,如果调用线程已被授予互斥体的初始所属权,则返回true  
        if (!flag)  
        {  
            Process instance = GetExistProcesses();  
            if (instance != null)  
            {  
                SetForeground(instance);  
                return;  
             }  
         }  
    GetExistProcesses()和 SetForeground(Process instance)的实现如下,这两个方法的作用就是:如果互斥体发现已经存在同名的互斥,就找到当前同名的进程,然后把这个进行的主窗体显示到屏幕的最前端。

            private static Process GetExistProcess()
            {
                Process currentProcess = Process.GetCurrentProcess();
                foreach (Process process in Process.GetProcessesByName(currentProcess.ProcessName))
                {
                    if (process.Id != currentProcess.Id && IsTheSameMainModule(currentProcess, process))
                    {
                        return process;
                    }
                }
                return null;
            }
            private static bool IsTheSameMainModule(Process currentProcess, Process process)
            {
                try
                {
                    return string.Equals(currentProcess.MainModule.ModuleName, process.MainModule.ModuleName);
                }
                catch (Win32Exception)
                {
                }
                return true;
            }
            private static void SetForegroundWindow(Process instance)
            {
                IntPtr mainFormHandle = instance.MainWindowHandle;
                if (mainFormHandle != IntPtr.Zero)
                {
                    HandleRef mainFormhr = new HandleRef(instance, mainFormHandle);
                    ShowWindowAsync(mainFormhr, 1);
                    SetForegroundWindow(mainFormhr);
                }
            }
            [DllImport("user32.dll", ExactSpelling = true)]
            public extern static bool ShowWindowAsync(HandleRef hWnd, int nCmdShow);
            [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
            public extern static bool SetForegroundWindow(HandleRef hWnd);        
    View Code
  • 相关阅读:
    【2018 “百度之星”程序设计大赛
    分班级(经典二分)
    【2018 “百度之星”程序设计大赛
    【zznu-夏季队内积分赛3-J】追忆
    常见网络名词解释
    【zznu-夏季队内积分赛3-G】2333
    【zznu-夏季队内积分赛3-F】学无止境
    【zznu-夏季队内积分赛3-I】逛超市
    html/css/javascript练习代码
    花生壳免费域名80端口无法访问问题处理
  • 原文地址:https://www.cnblogs.com/yuqf/p/4178637.html
Copyright © 2011-2022 走看看