2014-02-28 45 views
0

當我開發Windows服務時,我遇到了一個奇怪的情況。For循環原因IndexOutOfBoundException

我有一個MonitorOutputFile,其中我實現了方法MonitorOutputFile中的FileSystemWatcher。

當我寫的代碼如下

foreach (string filePath in filePathValue) 
{new Thread(() => monitorController.MonitorOutputFile(filePath, pollRetryInterval, fileWaitTime)).Start();} 

- >它運作良好的的OnStart();

然而,當我使用

for(int i=0;i<filePathValue.Length;i++) 
{ 
new Thread(() => monitorController.MonitorOutputFile(filePathValue[i], pollRetryInterval, fileWaitTime)).Start(); 
} 

- >這擲IndexOutOfBoundException在的OnStart()方法。

我地合計這是我的問題,所以我做了輸出

for(int i=0;i<filePathValue.Length;i++) 
{ 
EventLog.WriteEntry(SourceName, filePathValue[i], EventLogEntryType.Information, 58987); 
} 

- >此能夠輸出filePathValue [I]的正確的輸出。

不像Thread causing IndexOutOfBoundException 這是期待一個返回值,我的Windows服務不會等待任何返回值。這兩個有相似之處嗎?

有人可以告訴我爲什麼會發生這種情況?希望有人能夠與我分享這個奇怪的案例。

+0

我希望標記所有答案,這有助於我更多地瞭解lambda。謝謝大家:)星期五歡呼。 –

回答

3

您的lambda捕獲最後的i值,即filePathValue.Length。試試這個:

for (int i = 0; i < filePathValue.Length; i++) 
{ 
    int i1 = i; 
    new Thread(
     () => monitorController.MonitorOutputFile(
      filePathValue[i1], pollRetryInterval, fileWaitTime)).Start(); 
} 
+1

這非常依賴於C#版本,但這是可能的解釋。 –

+0

@BartvanNierop No;在所有版本的C#中,這是行爲。 –

+3

@BartvanNierop:行爲在C#5中改變了'foreach'變量,但不是'for'計數器。 – Douglas

1

這是一個常見問題。您正在使用匿名方法捕獲循環計數器,因此所有線程在執行後都可能會讀取相同(最終)的值i。相反,您應該將i分配給循環體內聲明的變量,以確保每個線程都讀取自己的副本。

for(int i=0;i<filePathValue.Length;i++) 
{ 
    int iInner = i; 
    new Thread(() => monitorController.MonitorOutputFile(filePathValue[iInner], pollRetryInterval, fileWaitTime)).Start(); 
} 
1

當變量i作爲參數發送到lambda表達式時。當在線程中執行lamba表達式時,for循環已經完成。所以你可以創建一個內部變量來保存該值。我認爲你可以嘗試下面的代碼,它應該是工作

for(int i=0;i<filePathValue.Length;i++) 
{ 
    var fileValue =filePathValue[i]; 
new Thread(() => monitorController.MonitorOutputFile(fileValue, pollRetryInterval, fileWaitTime)).Start(); 
}