Performing LIFO operations with ConcurrentStack

ConcurrentStack is the thread safe counterpart of Systems.Collections.Generic.Stack, which is the standard Last-In-First-Out (LIFO) container in the .NET Framework. For algorithms that favor stack usage such as depth-first searches, a thread safe stack is a big benefit.

In this recipe we are going to take a look at the basic usage of ConcurrentStack. Our Console application for this recipe will initialize a range of data, which a simple producer Task will push onto the stack. Consumer Task will concurrently pop items from the stack and write them to Console.

How to do it…

Now, let's take a look at performing LIFO operations with ConcurrentStack.

  1. Start a new project using the C# Console Application project template and assign ConcurrentStack as the Solution name.
  2. Add the following using directives to the top of your Program class:
    using System;
    using System.Collections.Concurrent;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
  3. First, in the Main method of the Program class, let's create our range of input data and our blocking collection.
    var data = Enumerable.Range(0, 100);
    ConcurrentStack<int> stack = new ConcurrentStack<int>();
  4. Next, let's create a simple producer task which will use a for loop to iterate through the numbers of our source data and pop them onto the stack.
    // producer 
    Task.Factory.StartNew(() =>
    {
        foreach (var item in data)
        {
            stack.Push(item);
            Console.WriteLine("Pushing item onto stack:{0} Item Count={1}", 
          item, stack.Count);
        }
    });
  5. Now let's create a consumer Task which will use a while loop to pop items off the stack while the IsEmpty property of the stack is false. Finish by waiting for user input before exiting.
    //consumer
    Task.Factory.StartNew(() =>
    {
        Thread.SpinWait(1000000);
        while (!stack.IsEmpty)
        {
            int result = 0;
            stack.TryPop(out result);
            Console.WriteLine("Popping item from stack:{0} Item Count={1}", 
          result, stack.Count);
        }
    });
    Console.ReadLine();
  6. In Visual Studio 2012, press F5 to run the project. You should see the output as shown in the following screenshot:
    How to do it…

How it works…

ConcurrentStack achieves thread safe access by using the System.Threading.Interlocked operations. Interlocked operations provide a simple mechanism for synchronizing access to variables shared by multiple threads. Interlocked operations are also very fast.

For the most part, ConcurrentStack behaves like System.Collections.Generic.Stack. To push an item onto the stack, you just use the Push method.

foreach (var item in data)
{
    stack.Push(item);
    Console.WriteLine("Pushing item onto stack:{0} Item Count={1}", 
    item, stack.Count);
}

However, the Pop method was removed in favor of TryPop. TryPop returns true if an item existed and was popped, otherwise it returns false. The out parameter contains the object removed if the pop was successful, otherwise it is indeterminate.

while (!stack.IsEmpty)
{
    int result = 0;
    stack.TryPop(out result);
    Console.WriteLine("Popping item from stack:{0} Item Count={1}", 
    result, stack.Count);
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.3.104