C# For循环原因IndexOutOfBoundException
我今天在开发windows服务时遇到了一个奇怪的情况 我有一个MonitorOutputFile,在其中我在方法MonitorOutputFile中实现FileSystemWatcher 当我写下面的代码时C# For循环原因IndexOutOfBoundException,c#,.net,C#,.net,我今天在开发windows服务时遇到了一个奇怪的情况 我有一个MonitorOutputFile,在其中我在方法MonitorOutputFile中实现FileSystemWatcher 当我写下面的代码时 foreach (string filePath in filePathValue) {new Thread(() => monitorController.MonitorOutputFile(filePath, pollRetryInterval, fileWaitTime)).St
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();
}
for(int i=0;i monitorController.MonitorOutputFile(filePathValue[i],pollRetryInterval,fileWaitTime)).Start();
}
-->此操作将在OnStart()方法中引发IndexOutOfBoundException
我知道这是我的问题,所以我做了一个输出
for(int i=0;i<filePathValue.Length;i++)
{
EventLog.WriteEntry(SourceName, filePathValue[i], EventLogEntryType.Information, 58987);
}
for(int i=0;我能够输出filePathValue[i]的正确输出
不像
我的windows服务不等待任何返回值。这两者有相似之处吗
有人能告诉我为什么会发生这种情况吗?希望有人能与我分享一些关于这个奇怪案例的信息。您的lambda捕获最后一个i
值,即filePathValue.Length
。尝试以下操作:
for (int i = 0; i < filePathValue.Length; i++)
{
int i1 = i;
new Thread(
() => monitorController.MonitorOutputFile(
filePathValue[i1], pollRetryInterval, fileWaitTime)).Start();
}
for(int i=0;imonitorController.MonitorOutputFile(
filePathValue[i1],pollRetryInterval,fileWaitTime)).Start();
}
您的lambda捕获最后一个i
值,即filePathValue.Length
。请尝试以下操作:
for (int i = 0; i < filePathValue.Length; i++)
{
int i1 = i;
new Thread(
() => monitorController.MonitorOutputFile(
filePathValue[i1], pollRetryInterval, fileWaitTime)).Start();
}
for(int i=0;imonitorController.MonitorOutputFile(
filePathValue[i1],pollRetryInterval,fileWaitTime)).Start();
}
这是一个常见问题。您在匿名方法中捕获循环计数器,因此所有线程在执行后都可能读取与i
相同的(最终)值。相反,您应该将i
分配给循环体中声明的变量,确保每个线程都读取自己的副本
for(int i=0;i<filePathValue.Length;i++)
{
int iInner = i;
new Thread(() => monitorController.MonitorOutputFile(filePathValue[iInner], pollRetryInterval, fileWaitTime)).Start();
}
for(int i=0;i monitorController.MonitorOutputFile(filePathValue[iInner],pollRetryInterval,fileWaitTime)).Start();
}
这是一个常见问题。您在匿名方法中捕获循环计数器,因此所有线程在执行后都可能读取与i
相同的(最终)值。相反,您应该将i
分配给循环体中声明的变量,确保每个线程都读取自己的副本
for(int i=0;i<filePathValue.Length;i++)
{
int iInner = i;
new Thread(() => monitorController.MonitorOutputFile(filePathValue[iInner], pollRetryInterval, fileWaitTime)).Start();
}
for(int i=0;i monitorController.MonitorOutputFile(filePathValue[iInner],pollRetryInterval,fileWaitTime)).Start();
}
当变量i作为参数发送到lambda表达式时。当lamba表达式在线程中执行此操作时,for循环将已完成。因此,您可以创建一个内部变量来保存该值。我认为您可以尝试下面的代码,它应该可以正常工作
for(int i=0;i<filePathValue.Length;i++)
{
var fileValue =filePathValue[i];
new Thread(() => monitorController.MonitorOutputFile(fileValue, pollRetryInterval, fileWaitTime)).Start();
}
for(int i=0;i monitorController.MonitorOutputFile(fileValue、pollRetryInterval、fileWaitTime)).Start();
}
当变量i作为参数发送到lambda表达式时。当lamba表达式在线程中执行此操作时,for循环将已完成。因此,您可以创建一个内部变量来保存该值。我认为您可以尝试下面的代码,它应该可以正常工作
for(int i=0;i<filePathValue.Length;i++)
{
var fileValue =filePathValue[i];
new Thread(() => monitorController.MonitorOutputFile(fileValue, pollRetryInterval, fileWaitTime)).Start();
}
for(int i=0;i monitorController.MonitorOutputFile(fileValue、pollRetryInterval、fileWaitTime)).Start();
}
这在很大程度上取决于C#版本,但这是可能的解释。@BartvanNierop不;在所有C#版本中,这就是行为。@BartvanNierop:在C#5中,foreach
变量的行为发生了变化,而不是for
计数器的行为。@Douglas我不知道。基于foreach
行为,我认为医学。假设是一切之母……:/谢谢。如果你对原理感兴趣,请阅读Eric Lippert:这在很大程度上取决于C#版本,但这是可能的解释。@BartvanNierop不;在C#的所有版本中,这就是行为。@BartvanNierop:行为在C#5中针对foreach
变量而不是 对于
计数器。@Douglas我不知道。基于
foreach行为,我假设。假设是一切之母…:/谢谢。如果您对原理感兴趣,请阅读Eric Lippert:我希望将所有标记为答案,这确实有助于我进一步了解lambda。谢谢大家:)为星期五干杯。我想把所有的都记下来作为答案,这确实帮助我了解更多关于lambda的事情。谢谢大家:)为周五干杯。