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?

Исходный код C# Circular Array отсюда.

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>();Это может быть то, что смутило вас.

Другие вопросы по тегам