using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Common.Extensions { /// /// Class NamedLock /// public class NamedLock : IDisposable { /// /// The _locks /// private readonly Dictionary _locks = new Dictionary(); /// /// Waits the async. /// /// The name. /// Task. public Task WaitAsync(string name) { return GetLock(name).WaitAsync(); } /// /// Releases the specified name. /// /// The name. public void Release(string name) { SemaphoreSlim semaphore; if (_locks.TryGetValue(name, out semaphore)) { semaphore.Release(); } } /// /// Gets the lock. /// /// The filename. /// System.Object. private SemaphoreSlim GetLock(string filename) { SemaphoreSlim fileLock; lock (_locks) { if (!_locks.TryGetValue(filename, out fileLock)) { fileLock = new SemaphoreSlim(1,1); _locks[filename] = fileLock; } } return fileLock; } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { Dispose(true); } /// /// Releases unmanaged and - optionally - managed resources. /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected virtual void Dispose(bool dispose) { if (dispose) { DisposeLocks(); } } /// /// Disposes the locks. /// private void DisposeLocks() { lock (_locks) { foreach (var semaphore in _locks.Values) { semaphore.Dispose(); } _locks.Clear(); } } } }