Ejemplo n.º 1
0
        public void ConcurrentEnqueAndDequeueMultiWriters()
        {
            // One reader assert all values should be received.
            Prop.ForAll <int[]>(expectedList =>
            {
                Array.Sort(expectedList);

                var queue = new ConcurrentAsyncQueue <int>();

                int numWriters = 4;

                var cancelSource = new CancellationTokenSource();
                CancellationToken cancelToken = cancelSource.Token;

                long remainingToRead = expectedList.Length;

                int startValue = 0;
                if (expectedList.Length > 0)
                {
                    startValue = expectedList[0];
                }

                var allTasks = new List <Task>();

                // can't move to separate fn because of `ref`
                var reader1 = ReaderTask(startValue, cancelToken, queue, (a, b) =>
                {
                    Interlocked.Decrement(ref remainingToRead);
                });

                allTasks.Add(reader1);

                for (int i = 0; i < numWriters; ++i)
                {
                    int myIndex = i;
                    allTasks.Add(Task.Run(() =>
                    {
                        for (int j = myIndex; j < expectedList.Length; j += numWriters)
                        {
                            queue.Enqueue(expectedList[j]);
                        }
                    }));
                }

                allTasks.Add(Task.Run(async() =>
                {
                    while (Interlocked.Read(ref remainingToRead) > 0)
                    {
                        await Task.Delay(10);
                    }

                    cancelSource.Cancel();
                }));

                Task.WaitAll(allTasks.ToArray());

                var actualList = reader1.Result;
                AssertIfNotEqual(expectedList, actualList);
            }).Check(testConfig);
        }
Ejemplo n.º 2
0
 static Task WriterTask <T>(T[] list, ConcurrentAsyncQueue <T> queue)
 {
     return(Task.Run(() =>
     {
         foreach (var x in list)
         {
             queue.Enqueue(x);
         }
     }));
 }
 async public Task <long> ConcurrentAsyncQueueEnqueueDequeue()
 {
     using (var asyncQueue = new ConcurrentAsyncQueue <int>())
     {
         long sum = 0;
         for (int i = 0; i < N; ++i)
         {
             asyncQueue.Enqueue(i);
             sum += await asyncQueue.DequeueAsync();
         }
         return(sum);
     }
 }
Ejemplo n.º 4
0
        public void ConcurrentEnqueAndDequeueHappensInOrder()
        {
            Prop.ForAll <int[]>(xs =>
            {
                var queue      = new ConcurrentAsyncQueue <int>();
                var writerTask = WriterTask(xs, queue);

                bool allSuccess = true;
                Task readerTask = Task.Run(async() =>
                {
                    foreach (var expected in xs)
                    {
                        var actual = await queue.DequeueAsync();
                        Assert.AreEqual(expected, actual);
                        allSuccess = allSuccess && (expected == actual);
                    }
                });

                Task.WaitAll(writerTask, readerTask);

                return(allSuccess);
            }).Check(testConfig);
        }
Ejemplo n.º 5
0
        public void ConcurrentEnqueAndDequeueMultiReaders()
        {
            // Multiple Readers assert that they receive values in increasing order.
            // All values should be received.
            Prop.ForAll <int[]>(expectedList =>
            {
                Array.Sort(expectedList);

                var queue        = new ConcurrentAsyncQueue <int>();
                var cancelSource = new CancellationTokenSource();
                CancellationToken cancelToken = cancelSource.Token;
                long remainingToRead          = expectedList.Length;
                int startValue = 0;

                if (expectedList.Length > 0)
                {
                    startValue = expectedList[0];
                }

                var allTasks = new List <Task>();

                // can't move to separate fn because of `ref`
                var reader1 = ReaderTask(startValue, cancelToken, queue, (a, b) =>
                {
                    Interlocked.Decrement(ref remainingToRead);
                    Assert.IsTrue(a >= b);
                });

                allTasks.Add(reader1);

                var reader2 = ReaderTask(startValue, cancelToken, queue, (a, b) =>
                {
                    Interlocked.Decrement(ref remainingToRead);
                    Assert.IsTrue(a >= b);
                });

                allTasks.Add(reader2);

                // writer task
                allTasks.Add(WriterTask(expectedList, queue));

                var reader3 = ReaderTask(startValue, cancelToken, queue, (a, b) =>
                {
                    Interlocked.Decrement(ref remainingToRead);
                    Assert.IsTrue(a >= b);
                });

                allTasks.Add(reader3);

                var reader4 = ReaderTask(startValue, cancelToken, queue, (a, b) =>
                {
                    Interlocked.Decrement(ref remainingToRead);
                    Assert.IsTrue(a >= b);
                });

                allTasks.Add(reader4);

                // Stop Task
                allTasks.Add(Task.Run(async() =>
                {
                    while (Interlocked.Read(ref remainingToRead) > 0)
                    {
                        await Task.Delay(10);
                    }

                    cancelSource.Cancel();
                }));

                Task.WaitAll(allTasks.ToArray());

                var actualList = MergeSortList(new List <int>[] { reader1.Result, reader2.Result, reader3.Result, reader4.Result });
                AssertIfNotEqual(expectedList, actualList);
            }).Check(testConfig);
        }
Ejemplo n.º 6
0
        static async Task <List <T> > ReaderTask <T>(T startValueRead, CancellationToken cancelToken, ConcurrentAsyncQueue <T> queue, Action <T, T> afterReadValue)
        {
            T lastValueRead = startValueRead;

            var list = new List <T>();

            while (!cancelToken.IsCancellationRequested)
            {
                T curValue = lastValueRead;
                try
                {
                    curValue = await queue.DequeueAsync(cancelToken);
                }
                catch (OperationCanceledException)
                {
                    break;
                }

                list.Add(curValue);

                afterReadValue(curValue, lastValueRead);

                lastValueRead = curValue;
            }

            return(list);
        }