今天,当我开发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服务不等待任何返回值。这两个有相似之处吗?
有人可以告诉我为什么会这样吗?希望有人能够在这个奇怪的案例中与我分享一些亮点。
答案 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();
}