What is a good pattern for using a Global Mutex in C#?

前端 未结 8 788
温柔的废话
温柔的废话 2020-11-21 23:16

The Mutex class is very misunderstood, and Global mutexes even more so.

What is good, safe pattern to use when creating Global mutexes?

One that will work

8条回答
  •  余生分开走
    2020-11-21 23:52

    Neither Mutex nor WinApi CreateMutex() works for me.

    An alternate solution:

    static class Program
    {
        [STAThread]
        static void Main()
        {
            if (SingleApplicationDetector.IsRunning()) {
                return;
            }
    
            Application.Run(new MainForm());
    
            SingleApplicationDetector.Close();
        }
    }
    

    And the SingleApplicationDetector:

    using System;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Security.AccessControl;
    using System.Threading;
    
    public static class SingleApplicationDetector
    {
        public static bool IsRunning()
        {
            string guid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
            var semaphoreName = @"Global\" + guid;
            try {
                __semaphore = Semaphore.OpenExisting(semaphoreName, SemaphoreRights.Synchronize);
    
                Close();
                return true;
            }
            catch (Exception ex) {
                __semaphore = new Semaphore(0, 1, semaphoreName);
                return false;
            }
        }
    
        public static void Close()
        {
            if (__semaphore != null) {
                __semaphore.Close();
                __semaphore = null;
            }
        }
    
        private static Semaphore __semaphore;
    }
    

    Reason to use Semaphore instead of Mutex:

    The Mutex class enforces thread identity, so a mutex can be released only by the thread that acquired it. By contrast, the Semaphore class does not enforce thread identity.

    << System.Threading.Mutex

    Ref: Semaphore.OpenExisting()

提交回复
热议问题