I ran into the same problem with many threads that can write in the same file.
One of the reasons that a mutex is not good is because it is slow:
duration of call mutexSyncTest: 00:00:08.9795826 duration of call NamedLockTest: 00:00:00.2565797
The BlockingCollection is a very good idea, but for my rare collision case, parallel recording is better than serial recording. Also, the dictionary path is much easier to implement.
I am using this solution ( UPDATED ):
public class NamedLock { private class LockAndRefCounter { public long refCount; } private ConcurrentDictionary<string, LockAndRefCounter> locksDictionary = new ConcurrentDictionary<string, LockAndRefCounter>(); public void DoWithLockBy(string key, Action actionWithLock) { var lockObject = new LockAndRefCounter(); var keyLock = locksDictionary.GetOrAdd(key, lockObject); Interlocked.Increment(ref keyLock.refCount); lock (keyLock) { actionWithLock(); Interlocked.Decrement(ref keyLock.refCount); if (Interlocked.Read(ref keyLock.refCount) <= 0) { LockAndRefCounter removed; locksDictionary.TryRemove(key, out removed); } } } }
gabba source share