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); }
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); } }