public async Task ConcurrentMany() { //**************************************** var Lock = new AsyncKeyedLock <int>(); //**************************************** using (var MySource = new CancellationTokenSource()) { var WorkTask1 = ConcurrentLockRelease(Lock, 42, 0, MySource.Token); var WorkTask2 = ConcurrentLockRelease(Lock, 42, 1, MySource.Token); var WorkTask3 = ConcurrentLockRelease(Lock, 42, 2, MySource.Token); await Task.Delay(500); MySource.Cancel(); await WorkTask1; await WorkTask2; await WorkTask3; } await Lock.DisposeAsync(); //**************************************** CollectionAssert.IsEmpty(Lock.KeysHeld); }
public async Task ConcurrentSlow() { //**************************************** var Lock = new AsyncKeyedLock <int>(); var Resource = 0; //**************************************** await Task.WhenAll( Enumerable.Range(1, 100).Select( async count => { if (count % 10 == 0) { Thread.Sleep(1); } await Task.Yield(); // Yield, so it doesn't serialise using (var MyWait = await Lock.Lock(count % 10)) { Interlocked.Increment(ref Resource); await Task.Delay(10); } return; }) ); //**************************************** Assert.AreEqual(100, Resource, "Block not entered"); CollectionAssert.IsEmpty(Lock.KeysHeld, "Lock still held"); }
public async Task Dispose() { //**************************************** var Lock = new AsyncKeyedLock <int>(); //**************************************** await Lock.DisposeAsync(); }
public async Task LockLockDispose() { //**************************************** var Lock = new AsyncKeyedLock <int>(); ValueTask MyDisposeTask; ValueTask <AsyncKeyedLock <int> .Instance> MyInnerTask; //**************************************** using (await Lock.Lock(42)) { MyInnerTask = Lock.Lock(42); MyDisposeTask = Lock.DisposeAsync(); } await MyDisposeTask; //**************************************** try { (await MyInnerTask).Dispose(); Assert.Fail("Should never reach this point"); } catch (ObjectDisposedException) { } }
public async Task LockCancelLock() { //**************************************** var Lock = new AsyncKeyedLock <int>(); ValueTask <AsyncKeyedLock <int> .Instance> SecondTask; //**************************************** var FirstLock = await Lock.Lock(42); using (var MySource = new CancellationTokenSource()) { SecondTask = Lock.Lock(42, MySource.Token); MySource.Cancel(); } var ThirdLockTask = Lock.Lock(42); Assert.IsFalse(ThirdLockTask.IsCompleted, "Third lock completed early"); FirstLock.Dispose(); var ThirdLock = await ThirdLockTask; //**************************************** try { await SecondTask; Assert.Fail("Should not reach this point"); } catch (OperationCanceledException) { } }
public async Task LockMaxTime() { //**************************************** var Lock = new AsyncKeyedLock <int>(); ValueTask <AsyncKeyedLock <int> .Instance> SecondTask; //**************************************** using (await Lock.Lock(42)) { SecondTask = Lock.Lock(42, TimeSpan.FromMilliseconds(50.0)); Thread.Sleep(100); } //**************************************** try { await SecondTask; Assert.Fail("Should not reach this point"); } catch (TimeoutException) { } }
public async Task LockCancel() { //**************************************** var Lock = new AsyncKeyedLock <int>(); ValueTask <AsyncKeyedLock <int> .Instance> SecondTask; //**************************************** var FirstLock = await Lock.Lock(42); using (var MySource = new CancellationTokenSource()) { SecondTask = Lock.Lock(42, MySource.Token); MySource.Cancel(); } //**************************************** try { await SecondTask; Assert.Fail("Should not reach this point"); } catch (OperationCanceledException) { } }
public void LockClass([Values(typeof(int), typeof(long), typeof(string), typeof(Version))] Type key) { //**************************************** var Lock = new AsyncKeyedLock <Type>(); //**************************************** var MyTask = Lock.Lock(key); //**************************************** Assert.IsTrue(MyTask.IsCompleted, "Lock did not complete"); CollectionAssert.AreEqual(new [] { key }, Lock.KeysHeld); }
public void LockStruct([Values(-1, 0, 1, int.MaxValue)] int key) { //**************************************** var Lock = new AsyncKeyedLock <int>(); //**************************************** var MyTask = Lock.Lock(key); //**************************************** Assert.IsTrue(MyTask.IsCompleted, "Lock did not complete"); CollectionAssert.AreEqual(new [] { key }, Lock.KeysHeld); }
public async Task LockRelease() { //**************************************** var Lock = new AsyncKeyedLock <int>(); //**************************************** var MyResult = await Lock.Lock(42); MyResult.Dispose(); //**************************************** CollectionAssert.IsEmpty(Lock.KeysHeld); }
public async Task LockDispose() { //**************************************** var Lock = new AsyncKeyedLock <int>(); ValueTask MyDisposeTask; //**************************************** using (await Lock.Lock(42)) { MyDisposeTask = Lock.DisposeAsync(); } await MyDisposeTask; }
public async Task LockInstant() { //**************************************** var Lock = new AsyncKeyedLock <int>(); //**************************************** using (await Lock.Lock(42, TimeSpan.FromMilliseconds(50.0))) { } //**************************************** CollectionAssert.IsEmpty(Lock.KeysHeld); }
public async Task LockNull() { //**************************************** var Lock = new AsyncKeyedLock <object>(); //**************************************** try { await Lock.Lock(null); Assert.Fail("Should not reach this point"); } catch (ArgumentNullException) { } }
public void LockTwo([Values(-1, 0, 1)] int first, [Values(-1, 0, 1)] int second) { //**************************************** var Lock = new AsyncKeyedLock <int>(); //**************************************** var MyTask1 = Lock.Lock(first); var MyTask2 = Lock.Lock(second); //**************************************** Assert.IsTrue(MyTask1.IsCompleted, "First lock did not complete"); Assert.AreEqual(first != second, MyTask2.IsCompleted, "Second lock was not as expected"); CollectionAssert.Contains(Lock.KeysHeld, first, "First key missing"); CollectionAssert.Contains(Lock.KeysHeld, second, "Second key missing"); }
//**************************************** private async Task ConcurrentLockRelease <TKey>(AsyncKeyedLock <TKey> keyedLock, TKey key, int delay, CancellationToken token) { while (!token.IsCancellationRequested) { using (await keyedLock.Lock(key)) { if (delay == 0) { await Task.Yield(); } else { await Task.Delay(delay); } } } }
public async Task DisposeLock() { //**************************************** var Lock = new AsyncKeyedLock <int>(); //**************************************** await Lock.DisposeAsync(); try { await Lock.Lock(42); Assert.Fail("Should never reach this point"); } catch (ObjectDisposedException) { } }
public async Task LockNoMaxTime() { //**************************************** var Lock = new AsyncKeyedLock <int>(); ValueTask <AsyncKeyedLock <int> .Instance> SecondTask; //**************************************** using (await Lock.Lock(42)) { SecondTask = Lock.Lock(42, TimeSpan.FromMilliseconds(50.0)); } //**************************************** (await SecondTask).Dispose(); CollectionAssert.IsEmpty(Lock.KeysHeld); }
public async Task LockDisposeLock() { //**************************************** var Lock = new AsyncKeyedLock <int>(); ValueTask MyDisposeTask; //**************************************** using (await Lock.Lock(42)) { MyDisposeTask = Lock.DisposeAsync(); try { await Lock.Lock(42); Assert.Fail("Should never reach this point"); } catch (ObjectDisposedException) { } } await MyDisposeTask; }
public async Task ConcurrentDispose() { //**************************************** var Lock = new AsyncKeyedLock <int>(); ValueTask MyDisposeTask; //**************************************** var WorkTask = ConcurrentLockRelease(Lock, 42, 0, CancellationToken.None); await Task.Delay(50); MyDisposeTask = Lock.DisposeAsync(); try { await WorkTask; Assert.Fail("Should not reach this point"); } catch (ObjectDisposedException) { } await MyDisposeTask; }