public async Task DisposeAsync_ExecuteTwice_UnlockOnce() { // arrange var memoryLock = new Mock <IInMemoryKeyLock>(); var acquired = new InMemoryAcquiredLock(TestLockKey, memoryLock.Object, DefaultExpiry); // act await acquired.DisposeAsync(); await acquired.DisposeAsync(); // assert memoryLock.Verify(x => x.Unlock(TestLockKey), Times.Once); }
public async Task DisposeAsync_ThreadSafety() { // arrange var readerWriterLock = new AsyncReaderWriterLock(); var writerLockHandle = readerWriterLock.WriterLock(); var finished = false; var memoryLock = new Mock <IInMemoryKeyLock>(); var acquired = new InMemoryAcquiredLock(TestLockKey, memoryLock.Object, DefaultExpiry); async Task TestLock() { while (!finished) { using (await readerWriterLock.ReaderLockAsync()) { await acquired.DisposeAsync(); } } } var tasks = Enumerable.Range(0, 3).Select(_ => Task.Run(TestLock)).ToList(); for (var i = 0; i < 50; i++) { writerLockHandle.Dispose(); await Task.Delay(1); writerLockHandle = readerWriterLock.WriterLock(); memoryLock.Verify(x => x.Unlock(TestLockKey), Times.AtMostOnce); memoryLock = new Mock <IInMemoryKeyLock>(); acquired = new InMemoryAcquiredLock(TestLockKey, memoryLock.Object, DefaultExpiry); } // assert finished = true; writerLockHandle.Dispose(); }