Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Challenge: The problem of locking down tasks…

DZone's Guide to

Challenge: The problem of locking down tasks…

· Database Zone ·
Free Resource

RavenDB vs MongoDB: Which is Better? This White Paper compares the two leading NoSQL Document Databases on 9 features to find out which is the best solution for your next project.  

The following code has very subtle bug:

    public class AsyncQueue
    {
        private readonly Queue<int> items = new Queue<int>();
        private volatile LinkedList<TaskCompletionSource<object>> waiters = new LinkedList<TaskCompletionSource<object>>();
     
        public void Enqueue(int i)
        {
            lock (items)
            {
               items.Enqueue(i);
               while (waiters.First != null)
               {
                   waiters.First.Value.TrySetResult(null);
                   waiters.RemoveFirst();
               }
           }
       }
    
       public async Task<IEnumerable<int>> DrainAsync()
       {
           while (true)
           {
               TaskCompletionSource<object> taskCompletionSource;
               lock (items)
               {
                   if (items.Count > 0)
                   {
                       return YieldAllItems();
                   }
                   taskCompletionSource = new TaskCompletionSource<object>();
                   waiters.AddLast(taskCompletionSource);
               }
               await taskCompletionSource.Task;
           }
       }
    
       private IEnumerable<int> YieldAllItems()
       {
           while (items.Count > 0)
           {
               yield return items.Dequeue();
           }
    
       }
   }

I’ll even give you a hint, try to run the following client code:

    for (int i = 0; i < 1000 * 1000; i++)
    {
        q.Enqueue(i);
        if (i%100 == 0)
        {
            Task.Factory.StartNew(async () =>
                {
                    foreach (var result in await q.DrainAsync())
                    {
                       Console.WriteLine(result);
                   }
               });
       }
    
   }
Can you figure out what the problem is?







Get comfortable using NoSQL in a free, self-directed learning course provided by RavenDB. Learn to create fully-functional real-world programs on NoSQL Databases. Register today.

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}