NullReferenceException в циклическом массиве / реализации буфера
Я реализую круговой массив / буфер в C#. Я получаю NullReferenceException
в строке 45 и 98. Кажется, в обход моего Initialize()
метод, а не настройка private int[] queue;
,
Учебный класс ThreadSafeCircularQueue
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CicrlaureArray
{
class ThreadSafeCircularQueue<T>
{
private int[] queue;
private int head = 0;
private int tail = 0;
private int length;
static Object thisLock = new Object();
public void CircularQueue()
{
Initialize();
}// end function CircularQueue
private void Initialize()
{
head = tail = -1;
Console.Write("Circular Queue size: ");
string length = Console.ReadLine();
this.length = int.Parse(length);
queue = new int[this.length];
}// end function Initialize
private void Enqueue(int value)
{
lock(thisLock)
{
if((head == 0 && tail == length - 1) || (tail + 1 == head))
{
Console.WriteLine("Circular queue is full.");
return;
}
else
{
if(tail == length - 1)
tail = 0;
else tail++;
//queue[tail] = value;
Console.WriteLine("In -> {0}", value);
}
if(head == -1)
head = 0;
}//end lock
}//end function Enqueue
private void Dequeue()
{
lock(thisLock)
{
int value;
if(head == -1)
{
Console.WriteLine("Circular queue is empty.");
value = -1;
}
else
{
value = queue[head];
queue[head] = 0;
if(head == tail)
head = tail = -1;
else if(head == length - 1)
head = 0;
else head++;
}
Console.WriteLine("Out -> {0}", value);
}//end lock
}//end function Enqueue
private void Show()
{
lock(thisLock)
{
int i;
if(head == -1)
{
Console.WriteLine("Circular queue is empty.");
return;
}
else
{
if(tail < head)
{
for(i = 0; i <= length - 1; i++)
Console.Write("{0} ", queue[i]);
}
else
for(i = 0; i <= tail; i++)
Console.Write("{0} ", queue[i]);
Console.WriteLine();
}
}//end lock
}//end function Show
public void EnqueueDequeue()
{
Enqueue(1);
Enqueue(2);
Enqueue(3);
Enqueue(4);
Show();
Enqueue(5);
Dequeue();
Dequeue();
Dequeue();
Dequeue();
Dequeue();
Dequeue();
Show();
Enqueue(6);
Show();
Enqueue(7);
Show();
Dequeue();
Dequeue();
Enqueue(8);
Enqueue(9);
Show();
}//end function EnqueueDequeue
}//end class ThreadSafeCircularQueue
}//end namespace CicrlaureArray
Главный
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using CicrlaureArray;
namespace CicrlaureArray
{
class Program
{
static void Main(string[] args)
{
ThreadSafeCircularQueue<int> CircularQueue = new ThreadSafeCircularQueue<int>();
Thread[] threads = new Thread[10];
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(new ThreadStart(CircularQueue.EnqueueDequeue));
}
for (int i = 0; i < threads.Length; i++)
{
threads[i].Start();
}
Console.ReadLine();
}//end function Main
}//end class Program
}//end namespace CicrlaureArray
Как мне решить NullReferenceException
?
2 ответа
Ты можешь позвонить CircularQueue()
сразу после создания очереди:
ThreadSafeCircularQueue<int> circularQueue = new ThreadSafeCircularQueue<int>();
circularQueue.CircularQueue();
Thread[] threads = new Thread[10];
...
или добавьте вызов конструктора CircularQueue()
public ThreadSafeCircularQueue()
{
CircularQueue();
}
также вы можете позвонить Initialize()
прямо в конструкторе и удали CircularQueue()
метод.
Initialize() никогда не вызывается, потому что вы неправильно настроили свой конструктор. У тебя есть
public void CircularQueue()
{
Initialize();
}// end function CircularQueue
в качестве конструктора для ThreadSafeCircularQueue
учебный класс. И это не правильно в этом контексте, если это так.
Так должно быть
public ThreadSafeCircularQueue()
{
Initialize();
}// end ThreadSafeCircularQueue constructor
чтобы это работало правильно. Кроме того, как правило, чтобы все были довольны, убедитесь, что вы придерживаетесь стиля форматирования C#. Переменные начинаются со строчной буквы (т.е. ThreadSafeCircularQueue<int> circularQueue = new ThreadSafeCircularQueue<int>();
Это может быть то, что смутило вас.