Cainnech
Cainnech

Reputation: 459

unexplainable Null exception error

In one of my applications I've created a sort of queue-list so that my application can send out midi-signals in the correct order.

So whenever I want to play a midi-note, I will add that midinote to a list.

I also have a backgroundworker running which will continuously check if there is note waiting in the "queue" and if there is, he will send it to the outputdevice.

Now I wanted to stresstest this, and 19 out of the 20 it works perfectly. Once every now and then, I get a nullexception error. The truth is that I don't know why it's giving me this error.

The only thing I can think of is that at the moment that the backgroundworker if checking if there is a note waiting in the queue, that there is a second argument which is still missing at that point which is why he trows an error.

However, when I look at the contents of the queue, it's all there.

So let me show you the code:

public class queueClass
{ 
    public int note {get; set;}
    public int delay { get; set; }

    public queueClass(int selectedNote, int selectedDelay)
    {
        note = selectedNote;
        delay = selectedDelay;
    }
}

List<queueClass> midiQueue = new List<queueClass>();

public void playNote(int noteNumber, int delay)
    { 
        if (Enabled)
        {
            // ADD THE NOTE TO THE QUEUE 
            midiQueue.Add(new queueClass(noteNumber, delay));

            if (!bgwMidi.IsBusy)
            {
                bgwMidi.RunWorkerAsync();
                Console.WriteLine(DateTime.Now + " >>> BACKGROUNDWORKER MIDI STARTED");

            }
        }

        
    }

 private void bgwMidi_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        while (worker.IsBusy)
        {
            if (worker.CancellationPending)
            {
                e.Cancel = true;
                break;
            }
            else
            {
                // CHECK IF THERE IS A MIDINOTE IN THE QUEUE
                if (midiQueue != null && midiQueue.Count > 0)
                {
                    if (midiQueue[0].note > -1 && midiQueue[0].delay > -1)
                    {
                        sendNote(midiQueue[0].note, midiQueue[0].delay);
                    }
                }
            }
        }
    }

The error is thrown on the first line of this code:

if (midiQueue[0].note > -1 && midiQueue[0].delay > -1)
{
   sendNote(midiQueue[0].note, midiQueue[0].delay);
}

and it says:

Object reference not set to an instance of an object

However when I look at my midiQueue it holds the values:

delay: 0

note: 5

For now I've tried to bypass the error by putting it into a try-catch block, but I would like to know what is causing this issue.

Does anybody have an idea on this?

Thanks!

Upvotes: 0

Views: 77

Answers (2)

Graffito
Graffito

Reputation: 1718

You should lock the midiqueue when Adding or removing items, if these operations are done in different threads.

When you push items:

lock (midiQueue) { midiQueue.Add(new queueClass(noteNumber, delay)); }

When you pop items:

lock (midiQueue) { /* the pop operation(s) */

When you use items:

lock (midiQueue)
{
   if (midiQueue != null && midiQueue.Count > 0)
   {
     if (midiQueue[0].note > -1 && midiQueue[0].delay > -1)
                    sendNote(midiQueue[0].note, midiQueue[0].delay);
   }
}

Upvotes: 4

PMerlet
PMerlet

Reputation: 2594

You check this :

midiQueue != null && midiQueue.Count > 0

So from there you know that you have an instanciated midiQueue and at least one element in midiQueue.

Then you do this :

midiQueue[0].note > -1 && midiQueue[0].delay > -1

And here is your problem. If midiQueue[0] is null then midiQueue[0].note will throw an "Object reference not set to an instance of an object" exception.

So you should modify your test :

if (midiQueue != null && midiQueue.Count > 0)
{
   if (midiQueue[0] != null && midiQueue[0].note > -1 && midiQueue[0].delay > -1)
   {
       sendNote(midiQueue[0].note, midiQueue[0].delay);
   }
}

Upvotes: 0

Related Questions