Over a million developers have joined DZone.

Challenge: The problem of locking down tasks…

· Database Zone

Learn NoSQL for free with hands-on sample code, example queries, tutorials, and more.  Brought to you in partnership with Couchbase.

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?







The Getting Started with NoSQL Guide will get you hands-on with NoSQL in minutes with no coding needed. Brought to you in partnership with Couchbase.

Topics:

Published at DZone with permission of Ayende Rahien, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

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

{{ parent.tldr }}

{{ parent.urlSource.name }}