public void WaitAndUnwrapExceptionResultWithCT_Faulted_UnwrapsException() { var cts = new CancellationTokenSource(); var task = TaskShim.Run((Func <int>)(() => { throw new NotImplementedException(); })); AssertEx.ThrowsException <NotImplementedException>(() => task.WaitAndUnwrapException(cts.Token), allowDerivedTypes: false); }
public async Task TestOperationCanceledExceptionsIgnored() { foreach (bool sync in DataflowTestHelpers.BooleanValues) { foreach (bool singleProducerConstrained in DataflowTestHelpers.BooleanValues) { var options = new ExecutionDataflowBlockOptions { SingleProducerConstrained = singleProducerConstrained }; int sumOfOdds = 0; Action <int> body = i => { if ((i % 2) == 0) { throw new OperationCanceledException(); } sumOfOdds += i; }; ActionBlock <int> ab = sync ? new ActionBlock <int>(body, options) : new ActionBlock <int>(async i => { await TaskShim.Yield(); body(i); }, options); const int MaxValue = 10; ab.PostRange(0, MaxValue); ab.Complete(); await ab.Completion; Assert.Equal( expected: Enumerable.Range(0, MaxValue).Where(i => i % 2 != 0).Sum(), actual: sumOfOdds); } } }
public void AsyncLock_CancelledLock_LeavesLockUnlocked() { Test.Async(async() => { var mutex = new AsyncLock(); var cts = new CancellationTokenSource(); var taskReady = new TaskCompletionSource(); var unlock = await mutex.LockAsync(); var task = TaskShim.Run(async() => { var lockTask = mutex.LockAsync(cts.Token); taskReady.SetResult(); await lockTask; }); await taskReady.Task; cts.Cancel(); await AssertEx.ThrowsExceptionAsync <OperationCanceledException>(task); Assert.IsTrue(task.IsCanceled); unlock.Dispose(); var finalLockTask = mutex.LockAsync(); await finalLockTask; }); }
public void StandardAsyncSingleConsumerCode() { Test.Async(async() => { var queue = new AsyncProducerConsumerQueue <int>(); var producer = TaskShim.Run(() => { queue.Enqueue(3); queue.Enqueue(13); queue.Enqueue(17); queue.CompleteAdding(); }); var results = new List <int>(); while (await queue.OutputAvailableAsync()) { results.Add(queue.Dequeue()); } Assert.AreEqual(results.Count, 3); Assert.AreEqual(results[0], 3); Assert.AreEqual(results[1], 13); Assert.AreEqual(results[2], 17); }); }
public async Task TestOrderMaintained() { foreach (bool sync in DataflowTestHelpers.BooleanValues) { foreach (bool singleProducerConstrained in DataflowTestHelpers.BooleanValues) { var options = new ExecutionDataflowBlockOptions { SingleProducerConstrained = singleProducerConstrained }; int prev = -1; Action <int> body = i => { Assert.Equal(expected: prev + 1, actual: i); prev = i; }; ActionBlock <int> ab = sync ? new ActionBlock <int>(body, options) : new ActionBlock <int>(i => TaskShim.Run(() => body(i)), options); ab.PostRange(0, 100); ab.Complete(); await ab.Completion; } } }
public async Task BufferBlocksToBatchNonGreedyToAction() { var inputs = Enumerable.Range(0, 1).Select(_ => new BufferBlock <int>()).ToList(); var b = new BatchBlock <int>(inputs.Count); int completedCount = 0; var c = new ActionBlock <int[]>(i => completedCount++); foreach (var input in inputs) { input.LinkTo(b); } var ignored = TaskShim.WhenAll(inputs.Select(s => s.Completion)).ContinueWith( _ => b.Complete(), CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default); b.LinkTo(c, new DataflowLinkOptions { PropagateCompletion = true }); for (int i = 0; i < Iterations; i++) { inputs[i % inputs.Count].Post(i); } foreach (var input in inputs) { input.Complete(); } await c.Completion; Assert.Equal(expected: Iterations / b.BatchSize, actual: completedCount); }
protected override async Task InitializeAsync() { await base.InitializeAsync(); IsBusy = true; try { await TaskShim.WhenAll(new[] { SetValueAsync(() => _systemIdentificationService.GetCpuId(), x => CpuId = x), SetValueAsync(() => _systemIdentificationService.GetGpuId(), x => GpuId = x), SetValueAsync(() => _systemIdentificationService.GetHardDriveId(), x => HardDriveId = x), SetValueAsync(() => _systemIdentificationService.GetMacId(), x => MacId = x), SetValueAsync(() => _systemIdentificationService.GetMotherboardId(), x => MotherboardId = x) }); // Note: we calculate the machine id last because we don't want to cause "false timings" in our demo app (the machine id // has to wait for all the others to finish so will take much longer then it actually does) await TaskHelper.Run(() => SetValueAsync(() => _systemIdentificationService.GetMachineId(), x => MachineId = x), true); } catch (Exception ex) { Log.Error(ex, "Failed to get system identification"); } IsBusy = false; }
public async Task TestMessagePostponement() { const int Excess = 10; foreach (int boundedCapacity in new[] { 1, 3 }) { var options = new ExecutionDataflowBlockOptions { BoundedCapacity = boundedCapacity }; foreach (var tb in new[] { new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable, options), new TransformManyBlock <int, int>(i => TaskShim.Run(() => DataflowTestHelpers.ToEnumerable(i)), options) }) { var sendAsync = new Task <bool> [boundedCapacity + Excess]; for (int i = 0; i < boundedCapacity + Excess; i++) { sendAsync[i] = tb.SendAsync(i); } tb.Complete(); for (int i = 0; i < boundedCapacity; i++) { Assert.True(sendAsync[i].IsCompleted); Assert.True(sendAsync[i].Result); } for (int i = 0; i < Excess; i++) { Assert.False(await sendAsync[boundedCapacity + i]); } } } }
public async Task TestSendAllThenReceive() { foreach (bool post in DataflowTestHelpers.BooleanValues) { foreach (bool sync in DataflowTestHelpers.BooleanValues) { Func <TransformManyBlock <int, int> > func = sync ? (Func <TransformManyBlock <int, int> >)(() => new TransformManyBlock <int, int>(i => new[] { i * 2 })) : (Func <TransformManyBlock <int, int> >)(() => new TransformManyBlock <int, int>(i => TaskShim.Run(() => Enumerable.Repeat(i * 2, 1)))); var network = DataflowTestHelpers.Chain <TransformManyBlock <int, int>, int>(4, func); const int Iters = 10; if (post) { network.PostRange(0, Iters); } else { await TaskShim.WhenAll(from i in Enumerable.Range(0, Iters) select network.SendAsync(i)); } for (int i = 0; i < Iters; i++) { Assert.Equal(expected: i * 16, actual: await network.ReceiveAsync()); } } } }
public void MultipleWaits_NotifyAll_AllAreCompleted() { Test.Async(async() => { var mutex = new AsyncLock(); var cv = new AsyncConditionVariable(mutex); var key1 = await mutex.LockAsync(); var task1 = cv.WaitAsync(); var __ = task1.ContinueWith(_ => key1.Dispose()); var key2 = await mutex.LockAsync(); var task2 = cv.WaitAsync(); var ___ = task2.ContinueWith(_ => key2.Dispose()); await TaskShim.Run(async() => { using (await mutex.LockAsync()) { cv.NotifyAll(); } }); await task1; await task2; }); }
public async Task TestLinkToOptions() { const int Messages = 1; foreach (bool append in DataflowTestHelpers.BooleanValues) { foreach (var tb in new[] { new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable), new TransformManyBlock <int, int>(i => TaskShim.Run(() => DataflowTestHelpers.ToEnumerable(i))) }) { var values = new int[Messages]; var targets = new ActionBlock <int> [Messages]; for (int i = 0; i < Messages; i++) { int slot = i; targets[i] = new ActionBlock <int>(item => values[slot] = item); tb.LinkTo(targets[i], new DataflowLinkOptions { MaxMessages = 1, Append = append }); } tb.PostRange(0, Messages); tb.Complete(); await tb.Completion; for (int i = 0; i < Messages; i++) { Assert.Equal( expected: append ? i : Messages - i - 1, actual: values[i]); } } } }
public async Task TestFaultingAndCancellation() { foreach (int boundedCapacity in new[] { DataflowBlockOptions.Unbounded, 1 }) { foreach (bool fault in DataflowTestHelpers.BooleanValues) { var cts = new CancellationTokenSource(); var bb = new BufferBlock <int>(new DataflowBlockOptions { CancellationToken = cts.Token, BoundedCapacity = boundedCapacity }); Task <bool>[] sends = Enumerable.Range(0, 4).Select(i => bb.SendAsync(i)).ToArray(); Assert.Equal(expected: 0, actual: await bb.ReceiveAsync()); Assert.Equal(expected: 1, actual: await bb.ReceiveAsync()); if (fault) { Assert.Throws <ArgumentNullException>(() => ((IDataflowBlock)bb).Fault(null)); ((IDataflowBlock)bb).Fault(new InvalidCastException()); await Assert.ThrowsAsync <InvalidCastException>(() => bb.Completion); } else { cts.Cancel(); await Assert.ThrowsAnyAsync <OperationCanceledException>(() => bb.Completion); } await TaskShim.WhenAll(sends); Assert.Equal(expected: 0, actual: bb.Count); } } }
public void TestInputCount() { foreach (bool sync in DataflowTestHelpers.BooleanValues) { Barrier barrier1 = new Barrier(2), barrier2 = new Barrier(2); Func <int, int> body = item => { barrier1.SignalAndWait(); // will test InputCount here barrier2.SignalAndWait(); return(item); }; TransformBlock <int, int> tb = sync ? new TransformBlock <int, int>(body) : new TransformBlock <int, int>(i => TaskShim.Run(() => body(i))); for (int iter = 0; iter < 2; iter++) { tb.PostItems(1, 2); for (int i = 1; i >= 0; i--) { barrier1.SignalAndWait(); Assert.Equal(expected: i, actual: tb.InputCount); barrier2.SignalAndWait(); } } } }
public async Task TestCircularLinking() { const int Iters = 200; foreach (bool sync in DataflowTestHelpers.BooleanValues) { var tcs = new TaskCompletionSource <bool>(); Func <int, int> body = i => { if (i >= Iters) { tcs.SetResult(true); } return(i + 1); }; TransformBlock <int, int> tb = sync ? new TransformBlock <int, int>(body) : new TransformBlock <int, int>(i => TaskShim.Run(() => body(i))); using (tb.LinkTo(tb)) { tb.Post(0); await tcs.Task; tb.Complete(); } } }
public void FuncBlock_Completed_CancelsFunc() { Test.Async(async() => { var tcs = new TaskCompletionSource(); var block = new FuncBlock <int>(async send => { try { while (true) { await send(13); await TaskShim.Delay(100); } } catch (OperationCanceledException) { tcs.SetResult(); } }); var resultTask = GetBlockOutputsAsync(block); block.Complete(); await resultTask; await block.Completion; await tcs.Task; }); }
public async Task TestExceptions() { var tb1 = new TransformManyBlock <int, int>((Func <int, IEnumerable <int> >)(i => { throw new InvalidCastException(); })); var tb2 = new TransformManyBlock <int, int>((Func <int, Task <IEnumerable <int> > >)(i => { throw new InvalidProgramException(); })); var tb3 = new TransformManyBlock <int, int>((Func <int, Task <IEnumerable <int> > >)(i => TaskShim.Run((Func <IEnumerable <int> >)(() => { throw new InvalidTimeZoneException(); })))); var tb4 = new TransformManyBlock <int, int>(i => ExceptionAfter(3)); var tb5 = new TransformManyBlock <int, int>(i => TaskShim.Run(() => ExceptionAfter(3))); for (int i = 0; i < 3; i++) { tb1.Post(i); tb2.Post(i); tb3.Post(i); tb4.Post(i); tb5.Post(i); } await Assert.ThrowsAsync <InvalidCastException>(() => tb1.Completion); await Assert.ThrowsAsync <InvalidProgramException>(() => tb2.Completion); await Assert.ThrowsAsync <InvalidTimeZoneException>(() => tb3.Completion); await Assert.ThrowsAsync <FormatException>(() => tb4.Completion); await Assert.ThrowsAsync <FormatException>(() => tb5.Completion); Assert.All(new[] { tb1, tb2, tb3 }, tb => Assert.True(tb.InputCount == 0 && tb.OutputCount == 0)); }
public void FuncBlock_Faulted_CancelsFunc() { Test.Async(async() => { var tcs = new TaskCompletionSource(); var block = new FuncBlock <int>(async send => { try { while (true) { await send(13); await TaskShim.Delay(100); } } catch (OperationCanceledException) { tcs.SetResult(); } }); ((IDataflowBlock)block).Fault(new NotImplementedException()); await tcs.Task; }); }
public async Task TestNullTasksIgnored() { foreach (int dop in new[] { DataflowBlockOptions.Unbounded, 1, 2 }) { var tb = new TransformManyBlock <int, int>(i => { if ((i % 2) == 0) { return(null); } return(TaskShim.Run(() => (IEnumerable <int>) new[] { i })); }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = dop }); const int Iters = 100; tb.PostRange(0, Iters); tb.Complete(); for (int i = 0; i < Iters; i++) { if ((i % 2) != 0) { Assert.Equal(expected: i, actual: await tb.ReceiveAsync()); } } await tb.Completion; } }
public async Task RemovesScheduledTasksAsync() { var timeService = new TimeService(TimeSpan.FromMinutes(1)); var schedulingService = new SchedulingService(timeService); var scheduledTask1 = new ScheduledTask { Name = "task 1", Start = timeService.CurrentDateTime.AddHours(5) }; schedulingService.AddScheduledTask(scheduledTask1); var scheduledTask2 = new ScheduledTask { Name = "task 2", Start = timeService.CurrentDateTime, Action = async() => { await TaskShim.Delay(TimeSpan.FromMinutes(1)); } }; schedulingService.AddScheduledTask(scheduledTask2); Assert.AreEqual(2, schedulingService.GetScheduledTasks().Count); schedulingService.RemoveScheduledTask(scheduledTask2); Assert.AreEqual(1, schedulingService.GetScheduledTasks().Count); }
public async Task TestOfferMessage() { var generators = new Func <TransformManyBlock <int, int> >[] { () => new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable), () => new TransformManyBlock <int, int>(DataflowTestHelpers.ToEnumerable, new ExecutionDataflowBlockOptions { BoundedCapacity = 10 }), () => new TransformManyBlock <int, int>(i => TaskShim.Run(() => DataflowTestHelpers.ToEnumerable(i)), new ExecutionDataflowBlockOptions { BoundedCapacity = 10, MaxMessagesPerTask = 1 }) }; foreach (var generator in generators) { DataflowTestHelpers.TestOfferMessage_ArgumentValidation(generator()); var target = generator(); DataflowTestHelpers.TestOfferMessage_AcceptsDataDirectly(target); DataflowTestHelpers.TestOfferMessage_CompleteAndOffer(target); target = generator(); await DataflowTestHelpers.TestOfferMessage_AcceptsViaLinking(target); DataflowTestHelpers.TestOfferMessage_CompleteAndOffer(target); } }
private async Task ValidateDateTimeRetrieval(Func <DateTime> normal, Func <DateTime> fast) { var normalNow1 = normal(); var fastNow1 = fast(); var delta1 = fastNow1 - normalNow1; if (delta1 < TimeSpan.Zero) { delta1 = TimeSpan.FromMilliseconds(delta1.TotalMilliseconds * -1); } Assert.IsTrue(delta1.TotalMilliseconds < 15); await TaskShim.Delay(5000); var normalNow2 = normal(); var fastNow2 = fast(); var delta2 = fastNow2 - normalNow2; if (delta2 < TimeSpan.Zero) { delta2 = TimeSpan.FromMilliseconds(delta2.TotalMilliseconds * -1); } Assert.IsTrue(delta2.TotalMilliseconds < 15); }
public async Task TestConsumeToAccept() { var wob = new WriteOnceBlock <int>(i => i * 2); wob.Post(1); await wob.Completion; var b2 = new BatchedJoinBlock <int, int>(1); wob.LinkTo(b2.Target2, new DataflowLinkOptions { PropagateCompletion = true }); Tuple <IList <int>, IList <int> > item2 = await b2.ReceiveAsync(); Assert.Equal(expected: 0, actual: item2.Item1.Count); Assert.Equal(expected: 1, actual: item2.Item2.Count); b2.Target1.Complete(); var b3 = new BatchedJoinBlock <int, int, int>(1); wob.LinkTo(b3.Target3, new DataflowLinkOptions { PropagateCompletion = true }); Tuple <IList <int>, IList <int>, IList <int> > item3 = await b3.ReceiveAsync(); Assert.Equal(expected: 0, actual: item3.Item1.Count); Assert.Equal(expected: 0, actual: item3.Item2.Count); Assert.Equal(expected: 1, actual: item3.Item3.Count); b3.Target1.Complete(); b3.Target2.Complete(); await TaskShim.WhenAll(b2.Completion, b3.Completion); }
public async Task TestSchedulerUsage() { foreach (bool singleProducerConstrained in DataflowTestHelpers.BooleanValues) { var scheduler = new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler; var sync = new ActionBlock <int>(_ => Assert.Equal(scheduler.Id, TaskScheduler.Current.Id), new ExecutionDataflowBlockOptions { TaskScheduler = scheduler, SingleProducerConstrained = singleProducerConstrained }); sync.PostRange(0, 10); sync.Complete(); await sync.Completion; var async = new ActionBlock <int>(_ => { Assert.Equal(scheduler.Id, TaskScheduler.Current.Id); return(TaskShim.FromResult(0)); }, new ExecutionDataflowBlockOptions { TaskScheduler = scheduler, SingleProducerConstrained = singleProducerConstrained }); async.PostRange(0, 10); async.Complete(); await async.Completion; } }
public async Task TestMaxNumberOfGroups() { foreach (bool greedy in DataflowTestHelpers.BooleanValues) { for (int maxNumberOfGroups = 1; maxNumberOfGroups <= 21; maxNumberOfGroups += 20) { for (int itemsPerBatch = 1; itemsPerBatch <= 3; itemsPerBatch += 2) { var batch = new BatchBlock <int>(itemsPerBatch, new GroupingDataflowBlockOptions { MaxNumberOfGroups = maxNumberOfGroups, Greedy = greedy }); // Feed all N batches; all should succeed for (int batchNum = 0; batchNum < maxNumberOfGroups; batchNum++) { var sendAsyncs = new Task <bool> [itemsPerBatch]; for (int itemNum = 0; itemNum < itemsPerBatch; itemNum++) { sendAsyncs[itemNum] = batch.SendAsync(itemNum); if (greedy) { Assert.True(sendAsyncs[itemNum].IsCompleted); Assert.True(sendAsyncs[itemNum].Result); } else if (itemNum < itemsPerBatch - 1) { Assert.False(sendAsyncs[itemNum].IsCompleted); } } await TaskShim.WhenAll(sendAsyncs); } // Next message should fail in greedy mode if (greedy) { var t = batch.SendAsync(1); Assert.Equal(expected: TaskStatus.RanToCompletion, actual: t.Status); Assert.False(t.Result); } // Make sure all batches were produced for (int i = 0; i < maxNumberOfGroups; i++) { int[] result = await batch.ReceiveAsync(); Assert.Equal(expected: itemsPerBatch, actual: result.Length); } // Next message should fail, even after groups have been produced if (!greedy) { var t = batch.SendAsync(1); Assert.Equal(expected: TaskStatus.RanToCompletion, actual: t.Status); Assert.False(t.Result); } } } } }
public async Task TestNonGreedy() { foreach (bool sync in DataflowTestHelpers.BooleanValues) { var barrier1 = new Barrier(2); Action <int> body = _ => barrier1.SignalAndWait(); var options = new ExecutionDataflowBlockOptions { BoundedCapacity = 1 }; ActionBlock <int> ab = sync ? new ActionBlock <int>(body, options) : new ActionBlock <int>(i => TaskShim.Run(() => body(i)), options); Task <bool>[] sends = Enumerable.Range(0, 10).Select(i => ab.SendAsync(i)).ToArray(); for (int i = 0; i < sends.Length; i++) { Assert.True(sends[i].Result); // Next send should have completed and with the value successfully accepted for (int j = i + 1; j < sends.Length; j++) // No further sends should have completed yet { Assert.False(sends[j].IsCompleted); } barrier1.SignalAndWait(); } ab.Complete(); await ab.Completion; } }
public async Task ShowsRunningAndScheduledTasks() { var timeService = new TimeService(TimeSpan.FromSeconds(1)); var schedulingService = new SchedulingService(timeService); var scheduledTask1 = new ScheduledTask { Name = "task 1", Start = timeService.CurrentDateTime.AddHours(5) }; schedulingService.AddScheduledTask(scheduledTask1); var scheduledTask2 = new ScheduledTask { Name = "task 2", Start = timeService.CurrentDateTime, Action = async() => { await TaskShim.Delay(TimeSpan.FromMinutes(1)); } }; schedulingService.AddScheduledTask(scheduledTask2); await TaskShim.Delay(TimeSpan.FromSeconds(1)); var summary = schedulingService.GetSummary(); Assert.IsNotNull(summary); }
public async Task TestReleasingOfPostponedMessages() { foreach (bool sync in DataflowTestHelpers.BooleanValues) { Barrier barrier1 = new Barrier(2), barrier2 = new Barrier(2); Action <int> body = i => { barrier1.SignalAndWait(); barrier2.SignalAndWait(); }; var options = new ExecutionDataflowBlockOptions { BoundedCapacity = 1 }; ActionBlock <int> ab = sync ? new ActionBlock <int>(body, options) : new ActionBlock <int>(i => TaskShim.Run(() => body(i)), options); ab.Post(0); barrier1.SignalAndWait(); Task <bool>[] sends = Enumerable.Range(0, 10).Select(i => ab.SendAsync(i)).ToArray(); Assert.All(sends, s => Assert.False(s.IsCompleted)); ab.Complete(); barrier2.SignalAndWait(); await ab.Completion; Assert.All(sends, s => Assert.False(s.Result)); } }
public void FuncBlock_Canceled_CancelsFunc() { Test.Async(async() => { var tcs = new TaskCompletionSource(); var cts = new CancellationTokenSource(); var block = new FuncBlock <int>(async send => { try { while (true) { await send(13); await TaskShim.Delay(100); } } catch (OperationCanceledException) { tcs.SetResult(); } }, new DataflowBlockOptions { CancellationToken = cts.Token, }); var resultTask = GetBlockOutputsAsync(block); cts.Cancel(); await resultTask; await tcs.Task; }); }
public void AsyncLock_Locked_PreventsLockUntilUnlocked() { Test.Async(async() => { var mutex = new AsyncLock(); var task1HasLock = new TaskCompletionSource(); var task1Continue = new TaskCompletionSource(); var task1 = TaskShim.Run(async() => { using (await mutex.LockAsync()) { task1HasLock.SetResult(); await task1Continue.Task; } }); await task1HasLock.Task; var task2Start = Task.Factory.StartNew(async() => { await mutex.LockAsync(); }); var task2 = await task2Start; Assert.IsFalse(task2.IsCompleted); task1Continue.SetResult(); await task2; }); }
public void WaitAndUnwrapExceptionWithCT_Faulted_UnwrapsException() { var cts = new CancellationTokenSource(); var task = TaskShim.Run(() => { throw new NotImplementedException(); }); AssertEx.ThrowsException <NotImplementedException>(() => task.WaitAndUnwrapException(cts.Token)); }