For循环导致IndexOutOfBoundException

时间:2014-02-28 13:15:57

标签: c# .net

今天,当我开发Windows服务时,我遇到了一个奇怪的情况。

我有一个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();
}

- &gt;这会在OnStart()方法中抛出IndexOutOfBoundException。

我知道这是我的问题,所以我做输出

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

- &gt;这能够输出filePathValue [i]。

的正确输出

Thread causing IndexOutOfBoundException不同 我期待一个返回值,我的Windows服务不等待任何返回值。这两个有相似之处吗?

有人可以告诉我为什么会这样吗?希望有人能够在这个奇怪的案例中与我分享一些亮点。

3 个答案:

答案 0 :(得分: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 :(得分:1)

这是一个常见问题。您正在匿名方法中捕获循环计数器,因此所有线程一旦执行,就可能读取i的相同(最终)值。相反,您应该将i分配给循环体内声明的变量,确保每个线程都读取自己的副本。

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

答案 2 :(得分: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();
}