Thursday, December 19, 2013

Cross process locking using a named mutex in C#

I needed to have some code be protected that only one process can execute it at a given time across processes. To do this I have used a featured called named mutexes in C# and .NET 4.5 (however you can do this in earlier versions. To make the code nice I wrote some little helpers as seen there

    public class CrossProcessLockFactory
    {
        private static int DefaultTimoutInMinutes = 2;
        public static IDisposable CreateCrossProcessLock()
        {
            return new ProcessLock(TimeSpan.FromMinutes(DefaultTimoutInMinutes));
        }

        public static IDisposable CreateCrossProcessLock(TimeSpan timespan)
        {
            return new ProcessLock(timespan);
        }
    }

    public class ProcessLock : IDisposable
    {
        // the name of the global mutex;
        private const string MutexName = "FAA9569-7DFE-4D6D-874D-19123FB16CBC-8739827-[SystemSpecicString]";

        private Mutex _globalMutex;

        private bool _owned = false;
        

        public ProcessLock(TimeSpan timeToWait)
        {
            try
            {
                _globalMutex = new Mutex(true, MutexName, out _owned);
                if (_owned == false)
                {
                    // did not get the mutex, wait for it.
                    _owned = _globalMutex.WaitOne(timeToWait);
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.Message);
                throw;
            }
        }

        public void Dispose()
        {
            if (_owned)
            {
                _globalMutex.ReleaseMutex();
            }            
            _globalMutex = null;
        }
    }

client code would look something like this:

    class Program
    {
        static void Main(string[] args)
        {
            using (CrossProcessLockFactory.CreateCrossProcessLock())
            {
                // if we get out it is ready
                Console.WriteLine("Using the mutex on process 1. Press any key to release the mutex");
                Console.ReadLine();
            }
        }
    }

This code can be improved to change the mutex name and the timespan from the client code. However for my needs this did the trick.

Update...

It is possible that a process that is holding a lock and owning the mutex dies. In this case the waiting process throws an exception of type AbandonedMutexException . It is a good idea to catch this exception, the process that catches this exception automatically owns the mutex now...

4 comments:

C Sharpens said...

Want to learn C# from basics & in most professional Code development style. I'll have you writing real working applications in no time flat-before you reach the end of course.
Hire C# Teacher.

Manjay said...

I am using your code. But when multiple applications calling this method only one thread is getting this lock and others are always in waiting state. I want it to be shared equally between threads.

Manjay said...
This comment has been removed by the author.
Smith said...

Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a .Net developer learn from .Net Core Training in Chennai. or learn thru .Net Core Training in Chennai. Nowadays Dot Net has tons of job opportunities on various vertical industry.
or Es6 Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry.