Example #1
0
        public void WaitAndPump(Task[] tasks)
        {
            while (true)
              {
            if (tasks.All(t => t.IsCompleted)) break;

            DoEvents();
              }
        }
Example #2
0
        public void FromCommandLineArgsRaceCondition() {
            // https://pytools.codeplex.com/workitem/1429

            var mre = new ManualResetEvent(false);
            var tasks = new Task<bool>[100];
            try {
                for (int i = 0; i < tasks.Length; i += 1) {
                    tasks[i] = Task.Run(() => {
                        mre.WaitOne();
                        using (var arg = VisualStudioProxy.FromProcessId(123)) {
                            return arg is VisualStudioProxy;
                        }
                    });
                }
                mre.Set();
                Assert.IsTrue(Task.WaitAll(tasks, TimeSpan.FromSeconds(30.0)));
                Assert.IsTrue(tasks.All(t => t.Result));
            } finally {
                mre.Dispose();
                Task.WaitAll(tasks, TimeSpan.FromSeconds(30.0));
            }
        }
Example #3
0
        public async Task ConcurrentOperationsAreSerialized()
        {
            byte[] data = Enumerable.Range(0, 1000).Select(i => (byte)i).ToArray();
            var mcaos = new ManuallyReleaseAsyncOperationsStream();
            var stream = new BufferedStream(mcaos, 1);

            var tasks = new Task[4];
            for (int i = 0; i < 4; i++)
            {
                tasks[i] = stream.WriteAsync(data, 250 * i, 250);
            }
            Assert.False(tasks.All(t => t.IsCompleted));

            mcaos.Release();
            await Task.WhenAll(tasks);

            stream.Position = 0;
            for (int i = 0; i < tasks.Length; i++)
            {
                Assert.Equal(i, stream.ReadByte());
            }
        }
        public void Should_control_executions_queuing_and_rejections_per_specification_with_cancellations(
            int maxParallelization, int maxQueuingActions, int totalActions, string because, bool cancelQueuing,
            bool cancelExecuting)
        {
            if (totalActions < 0) throw new ArgumentOutOfRangeException(nameof(totalActions));
            because = String.Format("MaxParallelization {0}; MaxQueuing {1}; TotalActions {2}; CancelQueuing {3}; CancelExecuting {4}: {5}", maxParallelization, maxQueuingActions, totalActions, cancelQueuing, cancelExecuting, because);

            BulkheadPolicy<ResultPrimitive> bulkhead = Policy.BulkheadAsync<ResultPrimitive>(maxParallelization, maxQueuingActions);

            // Set up delegates which we can track whether they've started; and control when we allow them to complete (to release their semaphore slot).
            actions = new TraceableAction[totalActions];
            for (int i = 0; i < totalActions; i++) { actions[i] = new TraceableAction(i, statusChanged, testOutputHelper); }

            // Throw all the delegates at the bulkhead simultaneously.
            Task<ResultPrimitive>[] tasks = new Task<ResultPrimitive>[totalActions];
            for (int i = 0; i < totalActions; i++) { tasks[i] = actions[i].ExecuteOnBulkheadAsync<ResultPrimitive>(bulkhead); }

            testOutputHelper.WriteLine("Immediately after queueing...");
            testOutputHelper.WriteLine("Bulkhead: {0} slots out of {1} available.", bulkhead.BulkheadAvailableCount, maxParallelization);
            testOutputHelper.WriteLine("Bulkhead queue: {0} slots out of {1} available.", bulkhead.QueueAvailableCount, maxQueuingActions);
            OutputActionStatuses();

            // Assert the expected distributions of executing, queuing, rejected and completed - when all delegates thrown at bulkhead.
            int expectedCompleted = 0;
            int expectedCancelled = 0;
            int expectedExecuting = Math.Min(totalActions, maxParallelization);
            int expectedRejects = Math.Max(0, totalActions - maxParallelization - maxQueuingActions);
            int expectedQueuing = Math.Min(maxQueuingActions, Math.Max(0, totalActions - maxParallelization));
            int expectedBulkheadFree = maxParallelization - expectedExecuting;
            int expectedQueueFree = maxQueuingActions - expectedQueuing;

            try
            {
                actions.Count(a => a.Status == TraceableActionStatus.Faulted).Should().Be(0);
                Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.Executing).Should().Be(expectedExecuting, because + ", when checking expectedExecuting"));
                Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.QueueingForSemaphore).Should().Be(expectedQueuing, because + ", when checking expectedQueuing"));
                Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.Rejected).Should().Be(expectedRejects, because + ", when checking expectedRejects"));
                actions.Count(a => a.Status == TraceableActionStatus.Completed).Should().Be(expectedCompleted, because + ", when checking expectedCompleted");
                actions.Count(a => a.Status == TraceableActionStatus.Canceled).Should().Be(expectedCancelled, because + ", when checking expectedCancelled");
                Within(shimTimeSpan, () => bulkhead.BulkheadAvailableCount.Should().Be(expectedBulkheadFree, because + ", when checking expectedBulkheadFree"));
                Within(shimTimeSpan, () => bulkhead.QueueAvailableCount.Should().Be(expectedQueueFree, because + ", when checking expectedQueueFree"));
            }
            finally
            {
                testOutputHelper.WriteLine("Expected initial state verified...");
                testOutputHelper.WriteLine("Bulkhead: {0} slots out of {1} available.", bulkhead.BulkheadAvailableCount, maxParallelization);
                testOutputHelper.WriteLine("Bulkhead queue: {0} slots out of {1} available.", bulkhead.QueueAvailableCount, maxQueuingActions);
                OutputActionStatuses();
            }

            // Complete or cancel delegates one by one, and expect others to take their place (if a slot released and others remain queueing); until all work is done.
            while (expectedExecuting > 0)
            {
                if (cancelQueuing)
                {
                    testOutputHelper.WriteLine("Cancelling a queueing task...");

                    actions.First(a => a.Status == TraceableActionStatus.QueueingForSemaphore).Cancel();

                    expectedCancelled++;
                    expectedQueuing--;
                    expectedQueueFree++;

                    cancelQueuing = false;
                }
                else if (cancelExecuting)
                {
                    testOutputHelper.WriteLine("Cancelling an executing task...");

                    actions.First(a => a.Status == TraceableActionStatus.Executing).Cancel();

                    expectedCancelled++;
                    if (expectedQueuing > 0)
                    {
                        expectedQueuing--;
                        expectedQueueFree++;
                    }
                    else
                    {
                        expectedExecuting--;
                        expectedBulkheadFree++;
                    }

                    cancelExecuting = false;
                }
                else // Complete an executing delegate.
                {
                    testOutputHelper.WriteLine("Completing a task...");

                    actions.First(a => a.Status == TraceableActionStatus.Executing).AllowCompletion();

                    expectedCompleted++;

                    if (expectedQueuing > 0)
                    {
                        expectedQueuing--;
                        expectedQueueFree++;
                    }
                    else
                    {
                        expectedExecuting--;
                        expectedBulkheadFree++;
                    }

                }

                try
                {
                    actions.Count(a => a.Status == TraceableActionStatus.Faulted).Should().Be(0);
                    Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.Executing).Should().Be(expectedExecuting, because + ", when checking expectedExecuting"));
                    Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.QueueingForSemaphore).Should().Be(expectedQueuing, because + ", when checking expectedQueuing"));
                    Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.Completed).Should().Be(expectedCompleted, because + ", when checking expectedCompleted"));
                    Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.Canceled).Should().Be(expectedCancelled, because + ", when checking expectedCancelled"));
                    actions.Count(a => a.Status == TraceableActionStatus.Rejected).Should().Be(expectedRejects, because + ", when checking expectedRejects");
                    Within(shimTimeSpan, () => bulkhead.BulkheadAvailableCount.Should().Be(expectedBulkheadFree, because + ", when checking expectedBulkheadFree"));
                    Within(shimTimeSpan, () => bulkhead.QueueAvailableCount.Should().Be(expectedQueueFree, because + ", when checking expectedQueueFree"));
                }
                finally
                {
                    testOutputHelper.WriteLine("End of next loop iteration...");
                    testOutputHelper.WriteLine("Bulkhead: {0} slots out of {1} available.", bulkhead.BulkheadAvailableCount, maxParallelization);
                    testOutputHelper.WriteLine("Bulkhead queue: {0} slots out of {1} available.", bulkhead.QueueAvailableCount, maxQueuingActions);
                    OutputActionStatuses();
                }
            }

            EnsureNoUnbservedTaskExceptions(tasks); 
            testOutputHelper.WriteLine("Verifying all tasks completed...");
            Within(shimTimeSpan, () => tasks.All(t => t.IsCompleted).Should().BeTrue());
        }
        private static bool TestMaxNumberOfGroups(bool greedy, bool sync)
        {
            Contract.Assert(greedy || !sync, "Non-greedy sync doesn't make sense.");
            bool passed = true;

            for (int maxNumberOfGroups = 1; maxNumberOfGroups <= 21; maxNumberOfGroups += 20)
            {
                for (int itemsPerBatch = 1; itemsPerBatch <= 1; itemsPerBatch++)
                {
                    var options = new GroupingDataflowBlockOptions { MaxNumberOfGroups = maxNumberOfGroups, Greedy = greedy };
                    var batch = new BatchBlock<int>(itemsPerBatch, options);

                    // 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++)
                        {
                            if (sync)
                            {
                                Assert.True(batch.Post(itemNum), string.Format("FAILED batch.Post({0}) on MaxNOG {1}", itemNum, batchNum));
                            }
                            else
                            {
                                sendAsyncs[itemNum] = batch.SendAsync(itemNum);
                            }
                        }
                        if (!sync)
                        {
                            Assert.True(Task.WaitAll(sendAsyncs, 4000),
                                string.Format("FAILED batch.SendAsyncs should have been completed in batch num {0}", batchNum));
                            if (passed)
                            {
                                Assert.True(sendAsyncs.All(t => t.Status == TaskStatus.RanToCompletion && t.Result),
                                    string.Format("FAILED batch.SendAsyncs should have been completed in batch num {0}", batchNum));
                            }
                        }
                    }

                    // Next message should fail in greedy mode
                    if (greedy)
                    {
                        if (sync)
                        {
                            Assert.False(batch.Post(1), "FAILED batch.Post(1) after completed groups should be declind");
                        }
                        else
                        {
                            var t = batch.SendAsync(1);
                            Assert.True(t != null && t.Status == TaskStatus.RanToCompletion && t.Result == false, "FAILED batch.SendAsync(1) after completed groups should be declined");
                        }
                    }

                    // Wait until the all batches are produced
                    Assert.True(SpinWait.SpinUntil(() => batch.OutputCount == maxNumberOfGroups, 4000), "FAILED All batches should have been produced");

                    // Next message should fail, even after groups have been produced
                    if (sync)
                    {
                        Assert.False(batch.Post(1), "FAILED batch.Post(1) after completed groups are output should be declind");
                    }
                    else
                    {
                        var t = batch.SendAsync(1);
                        Assert.True(t != null && t.Status == TaskStatus.RanToCompletion && t.Result == false, "FAILED batch.SendAsync(1) after completed groups are output should be declined");
                    }
                }
            }

            Assert.True(passed, string.Format("{0}", passed ? "Passed" : "FAILED"));
            return passed;
        }