Stack Empty Exception
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 lock
ed 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);
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 & 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, 2022Comments
-
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:
Can someone please explain?
-
Adam over 11 yearsWouldn't using the
ConcurrentStack<T>
as suggested by MBen be even more simple? -
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", akaTryPop
-
Marc Gravell over 11 years
ConcurrentStack<>
only hasTryPop
, so if (as per the question) you want a blocking-pop setup, it doesn't really get any simpler by using that API. -
MBen over 11 years@MarcGravell didn't see the blocking-pop :)
-
MBen over 11 years@MarcGravell still, isn't better to simplify the code using ConcurrentStack?
-
Marc Gravell over 11 yearsnot 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 over 11 yearsi'll try what you suggest & if it works i'll inform you with the results.
-
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 over 11 yearsYou 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 over 11 years@Quartermeister excellent, I learned something new. I updated the answer
-
Olivier Jacot-Descombes over 11 years... and before querying it!
-
Ibrahim Ahmed over 11 yearsi found that a BlockingCollection<T> is better for the purpose of my program.(Producer/Consumer)