0

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!

3
  • what are the values of midiQueue? When you set breakpoints and step through the code, is it populated? Are the delay and note properties populated? Commented Jul 3, 2015 at 9:49
  • Your error is not with ints being null.ints cannot be null, their default value is 0. Commented Jul 3, 2015 at 9:50
  • You're using multithreading using an unthreadsafe object - List<queueClass>. What happens if you put a lock around each place that you use midiQueue? Commented Jul 3, 2015 at 9:53

2 Answers 2

4

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);
   }
}
Sign up to request clarification or add additional context in comments.

4 Comments

I did try this and added the lock before adding or removing items. However, that did not work. I'm still getting the exception.
I updated my answer: you must also do a lock also when using the queue.
Thanks Graffito for the update, however I can't test it right now as the software is at work, and I won't be able to go there before tuesday, but I'll try it out then and keep you posted.
Well I've tested it and it still gives me issues. However, I don't think it's related to code, but I just think it's related to the Midi-output device. Because when I use the internal Synth-output, I don't have any issues. When I use my MidiSport output it occassionally crashes the entire system.
0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.