views:

721

answers:

2

I'm using a Mutex to make sure a webservice is only running once at a time, but I can't get it 100% right with WaitOnce and ReleaseMutex.

I've got this:

    private static Mutex mutex = new Mutex();

    [WebMethod]
    public bool TriggerAll()
    {
        bool ranJobs = false;
        try
        {
            if (mutex.WaitOne(0, false))
            {
                Thread.Sleep(10000); // simulate a long operation
                ranJobs = true;
            }
        }
        finally
        {
            mutex.ReleaseMutex();   
        }
        return ranJobs;
    }

I'f I try to access the webservice twice immediately, the second call doesn't return false but I get a ApplicationException from mutex.ReleaseMutex ("objectsyncronization method was called from an onsyncronized codeblock" - roughly translated from swedish)

What's the best way to do this?

+5  A: 

You're calling ReleaseMutex whether or not your WaitOne returned true. You should only call ReleaseMutex if you managed to acquire it:

    if (mutex.WaitOne(0, false))
    {
        try
        {
            Thread.Sleep(10000); // simulate a long operation
            ranJobs = true;
        }
        finally
        {
            mutex.ReleaseMutex();   
        }
    }

Is your mutex being used by multiple processes or AppDomains by the way? If not, a normal CLR monitor (using Monitor.TryEnter) would be lighter.

Jon Skeet
A: 

What means true or false here? In Wait function?

Creator