Stack Empty Exception

16,129

Solution 1

You must synchronize access when using something like Stack<T>. The simplest approach is to use lock, which then also let's you use the lock for the synchronization itself; so pop would be:

int item;
lock (SharedMemory)
{
    while (SharedMemory.Count == 0)
    {
        Monitor.Wait(SharedMemory);
    }
    item = SharedMemory.Pop();
}
Console.WriteLine(item);

and push would be:

lock (SharedMemory)
{
    SharedMemory.Push(item);
    Monitor.PulseAll(SharedMemory);
}

Solution 2

how is that possible the stack is full & has 16 items??!

In multithreading environment it is very much possible.

Are you using more than one threads in your program? If yes, SharedMemory should be locked before making any change to it.

Solution 3

If SharedMemory is a Stack, and since you are using Multithreading and if you are on .Net 4 . you should use : ConcurrentStack

Edit

After my first edit and a great comment from Quartermeister this a simpler working solution:

    int item;
    var SharedMemory = new BlockingCollection<int>(new ConcurrentStack<int>());
    // later in the Consume part
    item = SharedMemory.Take(); // this will block until there is an item in the list
    Console.WriteLine(item);
Share:
16,129
Ibrahim Ahmed
Author by

Ibrahim Ahmed

I am a developer with 5+ years of experience, worked in many types of projects, ranging from small company apps, startups, through enterprise apps, implementing and developing awesome useful applications. Skills &amp; Technologies • Frontend ​​​○ Javascript ○ ReactJS ○ CSS ○ HTML ○ React ○ Bootstrap ○ Semantic • Backend ○ NodeJS ○ ExpressJS ○ Loopback ○ Socket.IO ○ C# • Database ​​​○ MongoDB ○ SqlServer • Mobile ​​​○ ReactNative (iOS and Android)

Updated on June 07, 2022

Comments

  • Ibrahim Ahmed
    Ibrahim Ahmed almost 2 years

    I am getting a stack empty exception. How is that possible if the stack is not empty (it has 16 items)?

    I got a snap shot of the error:

    Stack Empty Exception

    Can someone please explain?

  • Adam
    Adam over 11 years
    Wouldn't using the ConcurrentStack<T> as suggested by MBen be even more simple?
  • Marc Gravell
    Marc Gravell over 11 years
    @codesparkle if it had a blocking Pop method, maybe; but it doesn't. It only has "get me something if something is there", aka TryPop
  • Marc Gravell
    Marc Gravell over 11 years
    ConcurrentStack<> only has TryPop, so if (as per the question) you want a blocking-pop setup, it doesn't really get any simpler by using that API.
  • MBen
    MBen over 11 years
    @MarcGravell didn't see the blocking-pop :)
  • MBen
    MBen over 11 years
    @MarcGravell still, isn't better to simplify the code using ConcurrentStack?
  • Marc Gravell
    Marc Gravell over 11 years
    not if it doesn't simplify it any; you'll still have most of the same code, and you'll need to think very carefully about thread-races between the gate being set and the "pop". By all means, though, feel free to edit in a robust implementation that behaves in the desired way. I just sincerely doubt it will be any simpler.
  • Ibrahim Ahmed
    Ibrahim Ahmed over 11 years
    i'll try what you suggest & if it works i'll inform you with the results.
  • MBen
    MBen over 11 years
    @MarcGravell You were right. Unfortunatly you get an exception that it is not locked (which is true). Would be nice if those collection offer some blocking mechanism like BlockingCollection<T>
  • Quartermeister
    Quartermeister over 11 years
    You can wrap the ConcurrentStack in a BlockingCollection. The default constructor of BlockingCollection uses a ConcurrentQueue, but there is another constructor that takes an IProducerConsumerCollection, and you can pass a ConcurrentStack to that constructor to get a blocking LIFO collection.
  • MBen
    MBen over 11 years
    @Quartermeister excellent, I learned something new. I updated the answer
  • Olivier Jacot-Descombes
    Olivier Jacot-Descombes over 11 years
    ... and before querying it!
  • Ibrahim Ahmed
    Ibrahim Ahmed over 11 years
    i found that a BlockingCollection<T> is better for the purpose of my program.(Producer/Consumer)