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

前端 未结 8 790
温柔的废话
温柔的废话 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:57

    Using the accepted answer I create a helper class so you could use it in a similar way you would use the Lock statement. Just thought I'd share.

    Use:

    using (new SingleGlobalInstance(1000)) //1000ms timeout on global lock
    {
        //Only 1 of these runs at a time
        RunSomeStuff();
    }
    

    And the helper class:

    class SingleGlobalInstance : IDisposable
    {
        //edit by user "jitbit" - renamed private fields to "_"
        public bool _hasHandle = false;
        Mutex _mutex;
    
        private void InitMutex()
        {
            string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value;
            string mutexId = string.Format("Global\\{{{0}}}", appGuid);
            _mutex = new Mutex(false, mutexId);
    
            var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
            var securitySettings = new MutexSecurity();
            securitySettings.AddAccessRule(allowEveryoneRule);
            _mutex.SetAccessControl(securitySettings);
        }
    
        public SingleGlobalInstance(int timeOut)
        {
            InitMutex();
            try
            {
                if(timeOut < 0)
                    _hasHandle = _mutex.WaitOne(Timeout.Infinite, false);
                else
                    _hasHandle = _mutex.WaitOne(timeOut, false);
    
                if (_hasHandle == false)
                    throw new TimeoutException("Timeout waiting for exclusive access on SingleInstance");
            }
            catch (AbandonedMutexException)
            {
                _hasHandle = true;
            }
        }
    
    
        public void Dispose()
        {
            if (_mutex != null)
            {
                if (_hasHandle)
                    _mutex.ReleaseMutex();
                _mutex.Close();
            }
        }
    }
    

提交回复
热议问题