2013-05-21 96 views
0

已解決:代碼每10毫秒通過事件執行,增加了事件之間花費的時間來解決問題。C#false if語句正在使用

我遇到了一個不應該發生的奇怪的IndexOutOfRangeException。即使語句本身是'錯誤',也正在使用if語句中的代碼。這是一個已知的問題嗎?如果是這樣,我該如何解決這個問題?

當計數器(int)爲0時發生錯誤,因此請求array燈光中的element -1

代碼:

if (counter > 0) 
    { 
    Console.WriteLine("counter-1 is groter dan 0"); 
    int i = counter - 1; 
    Lights[i].setState(0); 
    } 
+0

從其他線程訪問'counter'嗎? –

+0

我很抱歉,但那不可能是正確的。如果if語句爲false,那麼語句中的代碼將不會被執行,除非您有多線程問題。你可以發佈更多的代碼,以便我們看到你在做什麼? –

+0

錯誤的圖像可以在這裏看到:http://s13.postimg.org/a0frmariv/indexoutofrange.jpg我也很驚訝地看到它..應用程序是一個單線程應用程序和計數器是一個私人變量。 – Simon

回答

0

定時器觸發的事件每10ms。這創造的posibility:

  • 程序事件A期間獲得if語句裏面
  • 一個新的事件B被解僱和CPU照顧事件B的
  • 事件B改變計數器爲負值,從而使if語句爲假。
  • CPU將更改爲處理事件A.
  • 程序現在位於if語句中,即使if語句本身爲false也是如此。

該問題已經通過減少事件發生次數來解決。

+0

問題還沒有解決這只是可能會發生的 –

+0

使用互斥鎖來鎖定語句可能是一個選項,但這將需要我鎖定每一個可能導致問題的陳述。該計劃旨在運行在特定的硬件上,因此它的侷限性是已知的,並且在項目期間不會改變。 – Simon

1
除非

計數器被訪問/操縱在一個多線程的方式 - 這應該是一個不可能的狀態。

你總是可以嘗試使分配&檢查在同一個地方:

var index = 0; 

if ((index = (counter - 1)) > 0) 
{ 
    Lights[index].setState(0); 
} 
+0

這隻會讓代碼更難閱讀,也更難以調試imho。它對線程安全沒有任何幫助。 – Steve

0

如果沒有其他線程在後臺改變counter,那麼唯一可能的解釋是,​​集合大小爲零。

嘗試在訪問元素前檢查Lights的長度。

+0

但這是否解釋代碼正在執行,儘管條件評估爲false – tariq

+0

@tariq我不相信這是發生了什麼。我認爲實際發生的事情是'Lights []'具有零大小。但我同意鏈接圖片中的信息看起來很奇怪。調試器肯定將計數器顯示爲零。我懷疑一些奇怪的構建問題可能掩蓋了真正的原因。 –

+0

@MthetheWWatson:我認爲工具提示顯示計數器爲0,因爲在if語句輸入之前它是1,然後遞減(當前行是遞減後的行)。其他工具提示imho正在鼠標懸停進行評估,所以在那個時間點'counter> 0'是'false' – Gorgsenegger

1

如果這是一個沒有任何其他代碼變異的單線程應用counter,那麼最可能的解釋是Lights不夠長。例如,如果counter1(這是,我想你會同意,> 0 - 所以if測試將通過),並Lights是一個長度爲零的數組,然後Lights[i]Lights[0])將引發此異常 - 或者,如果counter200,但是Lights.Length199(或更少) - 如Lights[i]Lights[199])在範圍0-198之外。

檢查Lights.Length

+0

是的,這就是我的想法!但是當我查看調試器發佈的錯誤消息時,我變得非常不確定! (由於某種原因我不能在這裏重新發布鏈接......) –

0

嘗試這樣

int i=0; 
if (counter > 0) 
{ 
Console.WriteLine("counter-1 is groter dan 0"); 
i = counter - 1; 
Lights[i].setState(0); 
}