C# 导致IndexOutOfBounds异常的线程

C# 导致IndexOutOfBounds异常的线程,c#,multithreading,C#,Multithreading,这段代码导致IndexOutOfBoundsException 谁能告诉我为什么? 我无法理解为什么它会引起一种无法识别的感觉 private static String TRACE_PATH = "..\\..\\TRACES"; static void Main(string[] args) { if (Directory.Exists(TRACE_PATH)) { String[] traceEntries = Directory.GetFiles(TRA

这段代码导致IndexOutOfBoundsException 谁能告诉我为什么? 我无法理解为什么它会引起一种无法识别的感觉

private static String TRACE_PATH = "..\\..\\TRACES";

static void Main(string[] args)
{
    if (Directory.Exists(TRACE_PATH))
    {
        String[] traceEntries = Directory.GetFiles(TRACE_PATH);
        Thread[] traceReaders = new Thread[traceEntries.Length];


        for (int i = 0; i < traceEntries.Length; i++)
        {
            traceReaders[i] = new Thread(()=>readTrace(traceEntries[i]));
            traceReaders[i].Start();
        }

    }

    Console.Read();
}

private static void readTrace(String traceFile)
{
    using (StreamReader sr = new StreamReader(traceFile))
    {
       //code to use the trace file...
    }
}
private static String TRACE_PATH=“..\\..\\TRACES”;
静态void Main(字符串[]参数)
{
if(Directory.Exists(TRACE_PATH))
{
字符串[]traceEntries=Directory.GetFiles(跟踪路径);
Thread[]traceReaders=新线程[traceEntries.Length];
for(int i=0;ireadTrace(traceEntries[i]);
traceReaders[i].Start();
}
}
Console.Read();
}
私有静态void readTrace(字符串跟踪文件)
{
使用(StreamReader sr=新的StreamReader(traceFile))
{
//使用跟踪文件的代码。。。
}
}

只需在循环中声明一个临时变量。您捕获的是变量而不是值

 for (int i = 0; i < traceEntries.Length; i++)
 {
       var j = i;   
       traceReaders[j] = new Thread(()=>readTrace(traceEntries[j]));
       traceReaders[j].Start();
 }
for(int i=0;ireadTrace(traceEntries[j]);
traceReaders[j].Start();
}

只需在循环中声明一个临时变量。您捕获的是变量而不是值

 for (int i = 0; i < traceEntries.Length; i++)
 {
       var j = i;   
       traceReaders[j] = new Thread(()=>readTrace(traceEntries[j]));
       traceReaders[j].Start();
 }
for(int i=0;ireadTrace(traceEntries[j]);
traceReaders[j].Start();
}

我更喜欢这样写

for (int i = 0; i < traceEntries.Length; i++)
{
    var traceEntry = traceEntries[i];
    traceReaders[i] = new Thread(() => readTrace(traceEntry));
    traceReaders[i].Start();
}
for(int i=0;ireadTrace(traceEntry));
traceReaders[i].Start();
}
解释是变量
i
作为参数发送到lambda表达式。在线程上执行lamba表达式时,for循环将已经完成,因此
i
将等于
tracenties.Length

通过将
traceEntry
声明为局部变量,可以删除在for循环中更新的局部变量
i
的依赖关系


同样的事情也发生在L.B.的回答中。我想这是一个品味问题,如何处理它。

我更喜欢这样写

for (int i = 0; i < traceEntries.Length; i++)
{
    var traceEntry = traceEntries[i];
    traceReaders[i] = new Thread(() => readTrace(traceEntry));
    traceReaders[i].Start();
}
for(int i=0;ireadTrace(traceEntry));
traceReaders[i].Start();
}
解释是变量
i
作为参数发送到lambda表达式。在线程上执行lamba表达式时,for循环将已经完成,因此
i
将等于
tracenties.Length

通过将
traceEntry
声明为局部变量,可以删除在for循环中更新的局部变量
i
的依赖关系


同样的事情也发生在L.B.的回答中。我想这是一个如何处理的品味问题。

具体在哪一行?traceReaders[I]=新线程(()=>readTrace(traceEntries[I]);traceReaders[i].Start();具体在哪一行?traceReaders[i]=新线程(()=>readTrace(traceEntries[i]);traceReaders[i].Start();它起作用了。我知道这是因为lambda表达式,但你能解释一下背后的逻辑吗?@user2936347类似于。请注意,foreach循环的这种行为在c#5中发生了变化。0@user2936347实际上,您正在将
i
传递给lambda expr,而不是它的值。在一些线程启动时,for循环可能已经执行,
i
的值为
traceEntries.Length
。它可以工作。我知道这是因为lambda表达式,但你能解释一下背后的逻辑吗?@user2936347类似于。请注意,foreach循环的这种行为在c#5中发生了变化。0@user2936347实际上,您正在将
i
传递给lambda expr,而不是它的值。在某些线程启动时,for循环可能已执行,
i
的值为
traceEntries.Length