C# 导致IndexOutOfBounds异常的线程
这段代码导致IndexOutOfBoundsException 谁能告诉我为什么? 我无法理解为什么它会引起一种无法识别的感觉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
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
。