Skip to main content

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.

using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

//
// .NET 4.5 Parallel Extensions Cookbook
// Chapter 5: 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.
//
// https://www.packtpub.com/application-development/net-45-parallel-extensions-cookbook
//

namespace ConcurrentStack
{
    class Program
    {
        static void Main(string[] args)
        {
            var data = Enumerable.Range(0, 100);
            ConcurrentStack<int> stack = new ConcurrentStack<int>();

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

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