2015-07-03 73 views
0

在我的一個應用程序中,我創建了一種排隊列表,這樣我的應用程序就可以按照正確的順序發送midi信號。無法解釋的空異常錯誤

所以,每當我想播放一個midi音符時,我會將該midinote添加到列表中。

我也有一個backgroundworker正在運行,它將持續檢查在「隊列」中是否有註釋等待,如果有,他會將它發送到輸出設備。

現在我想強調一下,20箇中有19個完美地工作。偶爾一次,我會得到一個裸視錯誤。事實是,我不知道爲什麼它給了我這個錯誤。

我能想到的唯一的事情是,在背景工作者檢查是否有等待在隊列中的音符的那一刻,還有第二個參數仍然在那一點上丟失,這就是爲什麼他會播放錯誤。

但是,當我查看隊列的內容時,它就在那裏。

那麼讓我告訴你的代碼:

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

錯誤是扔在這段代碼的第一行:

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

和它說:

對象引用未設置爲對象的實例

然而,當我看着自己midiQueue其持有的價值觀:

延遲:0

注:5

現在我已經試圖把它變成繞過錯誤一個try-catch塊,但我想知道是什麼導致了這個問題。

有沒有人有這方面的想法?

謝謝!

+0

什麼midiQueue的價值?當您設置斷點並逐步完成代碼時,是否填充?是否填充了'delay'和'note'屬性? – user1666620

+0

您的錯誤不是'int's爲null .'int's不能爲null,它們的默認值爲0. –

+0

您正在使用多線程使用unthreadsafe對象 - '列表'。如果你在每個使用'midiQueue'的地方放置一個'lock',會發生什麼? – Enigmativity

回答

4

如果這些操作是在不同的線程中完成的,則應該在添加或刪除項目時鎖定midiqueue。

當你推的項目:

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

當你取出物品:

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

當您使用項目:

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

我嘗試過,並在添加或刪除項目之前添加了鎖。但是,這並不奏效。我仍然得到例外。 – Cainnech

+0

我更新了我的答案:在使用隊列時也必須執行鎖定。 – Graffito

+0

感謝Graffito的更新,但是現在我無法測試它,因爲軟件正在工作,並且我將無法在星期二之前去那裏,但我會嘗試一下,然後繼續發佈。 – Cainnech

0

您檢查:

midiQueue != null && midiQueue.Count > 0 

所以你知道你有一個instanciated midiQueue和至少一個midiQueue元素。

然後你這樣做:

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

這裏是你的問題。如果midiQueue [0]爲null,則midiQueue [0] .note將拋出「未設置爲對象實例的對象引用」異常。

所以,你應該修改你的測試:

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