コード例 #1
0
        public void TryWaitForNewItemsAsync_should_not_reset_event_after_partial_drain()
        {
            for (var i = 0; i < Capacity; i++)
            {
                queue.TryAdd(i.ToString()).Should().BeTrue();
            }

            queue.TryWaitForNewItemsAsync(1.Seconds()).Result.Should().BeTrue();

            queue.Drain(drainResult, 0, 1);

            queue.TryWaitForNewItemsAsync(1.Seconds()).Result.Should().BeTrue();
        }
コード例 #2
0
        private void StartLoggingTask()
        {
            Task.Run(
                async() =>
            {
                while (true)
                {
                    try
                    {
                        List <Waiter> currentWaiters;

                        lock (flushWaiters)
                        {
                            flushWaiters.RemoveAll(w => w.Task.IsCompleted);
                            currentWaiters = flushWaiters.Count > 0 ? flushWaiters.ToList() : EmptyWaitersList;
                        }

                        LogEvents();

                        foreach (var waiter in currentWaiters)
                        {
                            waiter.TrySetResult(true);
                        }
                    }
                    catch
                    {
                        await Task.Delay(100).ConfigureAwait(false);
                    }

                    await Task.WhenAny(events.TryWaitForNewItemsAsync(NewEventsTimeout), flushSignal.WaitAsync()).ConfigureAwait(false);

                    flushSignal.Reset();
                }
            });
        }
コード例 #3
0
        public void All_successfully_added_items_should_be_eventually_consumed(int capacity, int writersCount)
        {
            var addedItemsCount   = 0;
            var drainedItemsCount = 0;
            var queue             = new ConcurrentBoundedQueue <object>(capacity);
            var cancellation      = new CancellationTokenSource();
            var cancellationToken = cancellation.Token;

            var trigger = new CountdownEvent(writersCount + 1);
            var writers = Enumerable.Range(0, writersCount)
                          .Select(
                _ => Task.Run(
                    () =>
            {
                trigger.Signal();
                trigger.Wait();

                while (!cancellationToken.IsCancellationRequested)
                {
                    var item = new object();
                    if (queue.TryAdd(item))
                    {
                        Interlocked.Increment(ref addedItemsCount);
                    }
                }
            }))
                          .ToArray();

            var reader = Task.Run(
                async() =>
            {
                trigger.Signal();
                trigger.Wait();
                var buffer = new object[10];
                while (!cancellation.IsCancellationRequested || writers.Any(w => !w.IsCompleted) || queue.Count > 0)
                {
                    if (!await queue.TryWaitForNewItemsAsync(100.Milliseconds()).ConfigureAwait(false))
                    {
                        if (writers.Any(w => !w.IsCompleted))
                        {
                            throw new Exception("Wait seems to be stuck.");
                        }
                    }

                    var count          = queue.Drain(buffer, 0, buffer.Length);
                    drainedItemsCount += count;
                }
            });

            Thread.Sleep(10.Seconds());

            cancellation.Cancel();

            Task.WaitAll(writers);

            reader.Wait();

            Console.WriteLine($"added: {addedItemsCount}, drained: {drainedItemsCount}");

            queue.Count.Should().Be(0);
            drainedItemsCount.Should().Be(addedItemsCount);
        }