Should mutex.WaitOne() inside or before the try/finally block
I was wondering which of the foll开发者_运维百科owing was the suggested pattern when using Mutex (or Semaphores or ReadWriteLockSlims etc.).
Should the initial lock happen inside or outside of the try statement? Is it unimportant?
_mutex.WaitOne()
try
{
// critical code
}
finally
{
_mutex.ReleaseMutex();
}
or
try
{
_mutex.WaitOne()
// critical code
}
finally
{
_mutex.ReleaseMutex();
}
The only way these could be different is if an exception occurred after WaitOne but before the try start in example 1 or after the try start but before WaitOne in example 2. In the first case, the mutex won't be released and in the second case a release might be attempted even though there is no pending wait. The exception would have to be something severe like ThreadAbortException for it to occur in either place. However, if the mutex is contained in a using block, neither would be a problem.
EDIT: after reading Eric's post on this topic that Oliver linked to, I think even with a using block, the situation is not perfect and that simply going with your second version as Oliver suggests is your best option.
Maybe it is a different. Take a look into these posts from Eric:
- Subtleties of C# IL codegen
- Locks and exceptions do not mix
In short:
Just imagine there happens an exception between the mutex.WaitOne()
and the try
statement. You'll leave this chunk of code without calling the _mutex.ReleaseMutex()
.
So take your second piece of code to be sure everything works as expected.
If you´r not using the mutex for cross-process synchronization.
See answer to this question C# - Locking issues with Mutex
Then this will be safer:
private static object _syncLock = new object();
public void RunCriticalCode()
{
lock (_syncLock)
{
// critical code
}
}
精彩评论