public async Task TestLoadSyncAndAsync() { var l = new AsyncReaderWriterLock(); var lockStatistics = new LockStatistics(); var incorrectLockCount = false; var tasks = new Task[20]; var masterRandom = new Random(); var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(10)); for (var i = 0; i < tasks.Length; i++) { // Ensure that each random has its own unique seed var random = new Random(masterRandom.Next()); tasks[i] = i % 2 == 0 ? Task.Run(() => Lock(l, random, lockStatistics, CheckLockCount, CanContinue)) : LockAsync(l, random, lockStatistics, CheckLockCount, CanContinue); } await Task.WhenAll(tasks); Assert.That(incorrectLockCount, Is.False); void CheckLockCount() { if (!lockStatistics.Validate()) { Volatile.Write(ref incorrectLockCount, true); } } bool CanContinue() { return(!cancellationTokenSource.Token.IsCancellationRequested); } }
private static async Task LockAsync( AsyncReaderWriterLock readWriteLock, Random random, LockStatistics lockStatistics, System.Action checkLockAction, Func <bool> canContinue, CancellationToken cancellationToken = default(CancellationToken)) { while (canContinue()) { var isRead = random.Next(100) < 80; var releaser = isRead ? await(readWriteLock.ReadLockAsync()) : await(readWriteLock.WriteLockAsync()); lock (readWriteLock) { if (isRead) { lockStatistics.ReadLockCount++; } else { lockStatistics.WriteLockCount++; } checkLockAction(); } await(Task.Delay(10, cancellationToken)); lock (readWriteLock) { releaser.Dispose(); if (isRead) { lockStatistics.ReadLockCount--; } else { lockStatistics.WriteLockCount--; } checkLockAction(); } } }
private static void Lock( AsyncReaderWriterLock readWriteLock, Random random, LockStatistics lockStatistics, System.Action checkLockAction, Func <bool> canContinue) { while (canContinue()) { var isRead = random.Next(100) < 80; var releaser = isRead ? readWriteLock.ReadLock() : readWriteLock.WriteLock(); lock (readWriteLock) { if (isRead) { lockStatistics.ReadLockCount++; } else { lockStatistics.WriteLockCount++; } checkLockAction(); } Thread.Sleep(10); lock (readWriteLock) { releaser.Dispose(); if (isRead) { lockStatistics.ReadLockCount--; } else { lockStatistics.WriteLockCount--; } checkLockAction(); } } }