2

I have Queue code but throws NullReferenceException error.

public class BlockingQueue<T>
{
    private Queue<T> _queue;
    private Semaphore _sem;

    public int Count
    {
        get
        {
            return this._queue.Count;
        }
    }


    public T Dequeue()
    {
        T t;
        this._sem.WaitOne();
        lock (this._queue)
        {
            t = this._queue.Dequeue();
        }
        return t;
    }

    public void Enqueue(T item)  
    {
        // item have proper value but 
        // when insert value to Queue<T> _queue is null and I get NRE
        lock (this._queue)
        {
            this._queue.Enqueue(item);
        }
        this._sem.Release();
    }
}

enter image description here item have two value but when insert value to Queue _queue null value return error

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
jeon
  • 103
  • 1
  • 13

2 Answers2

1
public class BlockingQueue<T>
{
    private Queue<T> _queue = new Queue<T>;
    private Semaphore _sem -= new Semaphore();

    public int Count
    {
        get
        {
            return this._queue.Count;
        }
    }


    public T Dequeue()
    {
        T t;
        this._sem.WaitOne();
        lock (this._queue)
        {
            t = this._queue.Dequeue();
        }
        return t;
    }

    public void Enqueue(T item)  // < = item have two value but when insert value to Queue<t> _queue null value return error
    {
        lock (this._queue)
        {
            this._queue.Enqueue(item);
        }
        this._sem.Release();
    }
}
Alan Turing
  • 2,482
  • 17
  • 20
  • To clarify this answer, the difference between your code and this is the private fields have been initialized here. Merely defining the field does not create an instance of the object. – Chris Feb 25 '19 at 01:47
  • thanks so much for your help! i changed bit private Queue _queue = new Queue(); private Semaphore _sem = new Semaphore(1,2); – jeon Feb 25 '19 at 02:20
1

Your problem is initialisation.

However, if you are trying to create a thread-safe queue, I'd suggest using a BCL (FIFO) collection if possible, all the hard work has been done and tested for you.

ConcurrentQueue Class

Represents a thread-safe first in-first out (FIFO) collection.

It will be a more solid solution then what you have at this point, and has methods that will allow you more control and power of the queue.

Example

 // Construct a ConcurrentQueue.
  ConcurrentQueue<int> cq = new ConcurrentQueue<int>();

  // Populate the queue.
  for (int i = 0; i < 10000; i++)
  {
      cq.Enqueue(i);
  }

  // Peek at the first element.
  int result;
  if (!cq.TryPeek(out result))
  {
     Console.WriteLine("CQ: TryPeek failed when it should have succeeded");
  }
  else if (result != 0)
  {
     Console.WriteLine("CQ: Expected TryPeek result of 0, got {0}", result);
  }

  int outerSum = 0;
  // An action to consume the ConcurrentQueue.
  Action action = () =>
  {                
     int localSum = 0;
     int localValue;
     while (cq.TryDequeue(out localValue)) localSum += localValue;
     Interlocked.Add(ref outerSum, localSum);
  };

  // Start 4 concurrent consuming actions.
  Parallel.Invoke(action, action, action, action);

  Console.WriteLine("outerSum = {0}, should be 49995000", outerSum);
halfer
  • 19,824
  • 17
  • 99
  • 186
TheGeneral
  • 79,002
  • 9
  • 103
  • 141