0

My code seens to be allowing more than one thread to get into a specific method "protected" by mutex.

private static Mutex mut = new Mutex();
    public DadoMySql PegaPrimeiroFila(int identificacao)
    {
        DadoMySql dadoMySql = null;
        mut.WaitOne();


        dadoMySql = PegaPrimeiroFila_Processa();


        mut.ReleaseMutex();

        return dadoMySql;
    }

I have 10 threads and a keep getting 2 random ones of than getting the same "dadoMySql" everytime.

If i add logs inside de mutex wait everything works fine. The extra time it takes to write the log makes it work :/, maybe?

Danfus
  • 13
  • 1
  • What evidence do you have that makes you think that two or more threads have "owned" the mutex at the same time? Sounds like when you tried to prove it with logging, the logging proved the opposite of what you suppose. We don't know what behavior you saw, but is it possible that there's some other explanation for that behavior? – Solomon Slow Mar 13 '19 at 15:26

1 Answers1

0

Mutex is overkill here, unless you are synchronizing across multiple processes.

A simple lock should work since you want mutual exclusion:

private static readonly object lockObject = new object();

public DadoMySql PegaPrimeiroFila(int identificacao)
{
    DadoMySql dadoMySql = null;
    lock (lockObject)
    {
        dadoMySql = PegaPrimeiroFila_Processa();
    }
    return dadoMySql;
}

Using the lock keyword also gives you a stronger guarantee that Monitor.Exit nearly always gets called. A good example is when an exception is thrown inside of lock scope.

Zer0
  • 7,191
  • 1
  • 20
  • 34
  • Just curious. I see you write "stronger guarantee", how so? In case of a, say OutOfMemoryException, it will not release it? – Neijwiert Mar 13 '19 at 15:06
  • @Neijwiert See the [documentation](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement). In short, it uses `try ... finally`. – Zer0 Mar 13 '19 at 15:07
  • Yes I am aware of that. But how is that a 'stronger guarantee' as opposed to a 'guarantee'? – Neijwiert Mar 13 '19 at 15:09
  • I mean, it's definitely a stronger guarantee than the asker's code, which doesn't attempt to use `try()...finally()` – willaien Mar 13 '19 at 15:11
  • @Neijwiert Because `finally` is not 100% guaranteed to run. One example [here](https://stackoverflow.com/questions/3216046/does-the-c-sharp-finally-block-always-execute). – Zer0 Mar 13 '19 at 15:12
  • @willaien Right, I think my train of thought was narrowed down on `lock` vs `try`/`finally` with `Monitor.Enter` and `Monitor.Exit`. Instead of considering no try/finally – Neijwiert Mar 13 '19 at 15:13
  • @Zer0 Thanks for the example link, good question/answer read there for me. – Neijwiert Mar 13 '19 at 15:15
  • I actually have error handling...just removed it to keep the code simpler. I will use lock as it makes more sense, thank you. btw...my problem was bad coding somewhere else...i wasnt allowing the threads to read the data at the same time, but was allowing them to refresh the data when was empty... ty again! – Danfus Mar 13 '19 at 15:18