Lock Access to Multiple Resources with C# Mutex and WaitHandle.WaitAny

I came across a problem while developing a WCF service. I needed to increase the load handling capability, however the number of connections were limited and each needed to call an external service synchronously. I needed a mutex but I needed more than one at a time.

The lock statement wasn’t going to do the job because that will only allow one thread at a time into the critical section. What I needed was a mutex that would allow exactly 8 thread at one time.

Luckily there is a way to solve this problem with .NET libraries. The course of action is to create an array of Mutex objects and an array of your Manager objects. Using the method WaitHandle.WaitAny, you can wait for one of them to become available. At that point use the manager object with the same index.

The WaitAny call will block the thread until one of the resources becomes available. It returns the index of the lock that was taken, or a special value if a timeout occurred.

Here’s the code:

class Program
{
    private const int MANAGER_TIMEOUT = 5000;
    private const int MANAGER_COUNT = 6;
    private static Mutex[] ManagerLocks;
    private static ManagerOfSomeSort[] Managers;
 
    static Program()
    {
        ManagerLocks = new Mutex[MANAGER_COUNT];
        Managers = new ManagerOfSomeSort[MANAGER_COUNT];
        for (int i = 0; i < MANAGER_COUNT; i++)
        {
            ManagerLocks[i] = new Mutex();
            Managers[i] = new ManagerOfSomeSort();
        }
    }
 
    public void HandleRequest()
    {
        var index = WaitHandle.WaitAny(ManagerLocks, MANAGER_TIMEOUT);
        if (index == WaitHandle.WaitTimeout)
            return;  // log an timeout error perhaps
        try
        {
            var manager = Managers[index];
            manager.DoSomething();
        }
        finally
        {
            ManagerLocks[index].ReleaseMutex();
        }
    }
}

The Most Important Key on the Keyboard

The most popular keyboards in the US have 104 keys.  Some keyboards have more keys, some have less.  Some keyboards have numeric keypads on the right to allow you to type in long sequences of digits faster.  Some keyboard have altered layouts designed to fit on a laptop.  Despite the differences in keyboards there is a single key that can be considered the most important of all.

If you’re like me, you spend a lot of time during the day next to your keyboard hitting the keys in some prescribed manner.  Many of the common key sequences have been burned into my muscle memory so thoroughly that I don’t have to think about it.  When saving my documents I almost always use “Alf+F, S” rather than “Ctrl+S” because that’s the way my hand remembers how to save my document.

Beyond personal preference, there is one key that stands alone in both its importance, and on the keyboard itself: the “Esc” key.  It’s located in the upper left of the keyboard — the most important place on the keyboard for a left to right, top to bottom reading culture.  It’s also the easiest key to hit on the keyboard without looking. The “Esc” key has universal acceptance and intuitive functionality, although it can be difficult to put into words.

For a web browser the “Esc” key means to cancel the current request.  For a windows application, it might dismiss a dialog.  For a terminal application, it may return you to a home screen.  If you’re dragging a file from one folder to another, you can hit escape to cancel the drag operation.  Inside of a standard textbox, the “Esc” key will reset the text to its initial value.  (This particular usage is extremely useful if the application doesn’t allow you to switch focus with invalid data, and you don’t remember what was originally there.)  Essentially, it means “Stop what you’re doing and get me back to where I was”.

The “Esc” key is like a safety harness.  With it you can venture into the black depths of undocumented software and return with your data intact.  Whatever you do, wherever you go, you should always be able hit the “Esc” key and things will be alright.  The “Esc” key is comfortable and familiar.

We as developers must be mindful of the “Esc” key and how to make it work.  We should also recognize where it can work.  The “Esc” key can be used to dismiss error or information messages.  It can be used to cancel the current operation, but its operation should be ‘safe’.  You can lose some data, but not much.  (It’s okay to lose data that you just put into a dialog box.)  The user can and will hit the “Esc” key multiple times in a row in rapid succession.  Eventually, you should get to a place where the “Esc” key does nothing, or loops until the user performs a necessary action.  A good example of a loop is trying to exit a window where changes need to be saved.  “Esc” -> Exit.  Dialog, “Save Change?”  “Esc” -> Close dialog, return to window.

I think it can be easy to forget about the “Esc” key during software development.  Very often, it is a non-operation, but when appropriate, I think good handling of the “Esc” key is essential.