将空值返回队列并抛出NullReferenceException

时间:2019-02-25 01:39:40

标签: c# .net nullreferenceexception

我有队列代码,但抛出NullReferenceException错误。

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 项目具有两个值,但是当将值插入Queue _queue空值时返回错误

2 个答案:

答案 0 :(得分: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();
    }
}

答案 1 :(得分:1)

您的问题是初始化。

但是,如果您尝试创建线程安全队列,则id建议尽可能使用BCL (FIFO)集合,所有辛苦的工作已经为您完成并经过测试。

>

ConcurrentQueue Class

  

表示线程安全的先进先出(FIFO)集合。

这将是一个比您目前拥有的解决方案更扎实的解决方案,并且具有可以让您更好地控制和控制队列的方法

示例

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