/// <summary> /// Subscribe to the inner event /// </summary> public void Add(TFromHandler from) { var to = _convert(from); Transactional.Update(ref _handlers, h => h.Add(from, to)); _add(to); }
public async Task SimpleUpdateWith2Params() { var list = ImmutableList <int> .Empty; Transactional.Update(ref list, 42, 10000, (l, x, y) => l.Add(y - x)); list.Should().HaveCount(1); list[0].Should().Be(9958); }
public async Task SimpleUpdateWithTuple() { var list = ImmutableList <int> .Empty; var res = Transactional.Update(ref list, l => Tuple.Create(l.Add(42), 21)); list.Should().HaveCount(1); res.Should().Be(21); }
public async Task SimpleUpdateWith1Param() { var list = ImmutableList <int> .Empty; Transactional.Update(ref list, 42, (l, x) => l.Add(x)); list.Should().HaveCount(1); list[0].Should().Be(42); }
#pragma warning restore 1998 public IDisposable RegisterHandler(IHttpHandler handler) { Transactional.Update(ref _handlers, handler, (list, h) => list.Add(h)); _handlers.Add(handler); return(Disposable.Create(() => { Transactional.Update(ref _handlers, handler, (list, h) => list.Remove(h)); (handler as IDisposable)?.Dispose(); })); }
public void OnCompleted(Action continuation) { Transactional.Update( ref _continuations, continuation, (previous, c) => previous == null ? ImmutableList <Action> .Empty.Add(c) : previous.Add(c)); if (Termination != TerminationType.Running) { RaiseOnCompleted(); } }
/// <summary> /// Create a handler for this relative path /// </summary> /// <remarks> /// Disposing the return value will remove the unregister the handler. /// </remarks> public IDisposable RegisterHandler(IHttpHandler handler) { if (_handlers == null) { throw new ObjectDisposedException(nameof(RelativePathHandler)); } Transactional.Update(ref _handlers, handler, (list, h) => list.Add(h)); _handlers.Add(handler); return(Disposable.Create(() => { Transactional.Update(ref _handlers, handler, (list, h) => list.Remove(h)); (handler as IDisposable)?.Dispose(); })); }
public void When_Update_WithTwoParameter_ReturnsOriginalValue_Then_FastExit() { var value1 = new MyClass(); var value2 = new MyClass(); var obj = value1; var invocation = 0; Transactional.Update(ref obj, 1, 2, (o, _, __) => { invocation++; obj = value2; return(o); }); Assert.AreEqual(1, invocation); Assert.AreEqual(value2, obj); }
public void When_UpdateObject_ReturnsOriginalValue_Then_FastExit() { var value1 = new object(); var value2 = new object(); var obj = value1; var invocation = 0; Transactional.Update(ref obj, o => { invocation++; obj = value2; return(o); }); Assert.AreEqual(1, invocation); Assert.AreEqual(value2, obj); }
public void When_Update_WithProjectionAndOneParameter_ReturnsOriginalValue_Then_FastExit() { var value1 = new MyClass(); var value2 = new MyClass(); var obj = value1; var invocation = 0; Transactional.Update(ref obj, 1, (o, _) => { invocation++; obj = value2; return(Tuple.Create(o, new object())); }); Assert.AreEqual(1, invocation); Assert.AreEqual(value2, obj); }
public async Task AtomicUpdate() { var list = ImmutableList <int> .Empty; var ev = new AutoResetEvent(false); var runs1 = 0; var t = Task.Run(() => { Transactional.Update(ref list, l => { var ret = l.Add(42); // We've capture the list, release the thread that will create // the race condition ev.Set(); // Now wait for the race to happen ev.WaitOne(); runs1++; return(ret); }); }); // Wait for the other thread to have captured the list ev.WaitOne(); // Update the list reference while the other thread is updaint Transactional.Update(ref list, l => l.Add(42)); // Release the waiting thread. ev.Set(); await t; list.Should().HaveCount(2); runs1.Should().Be(2); }