C# - 在for循环中使用相同的列表大小,索引超出了数组的范围[重复]
Posted
技术标签:
【中文标题】C# - 在for循环中使用相同的列表大小,索引超出了数组的范围[重复]【英文标题】:C# - Index was outside the bounds of the array using same list sizes in for loop [duplicate] 【发布时间】:2017-10-26 07:41:25 【问题描述】:我正在.NET 中创建一个文件下载器,它使用异步任务从服务器下载一组文件。但是,即使我创建了 Task[]
并返回了相同长度的 string[]
。
这是我的方法:
public static string[] DownloadList(string[] urlArray, string[] toPathArray, string login = "", string pass = "", bool getExt = false)
Console.WriteLine("DownloadList(0, 1, 2, 3, 4)", urlArray, toPathArray, login, pass, getExt);
try
returnedArray = new string[urlArray.Length];
Task[] taskArray = new Task[urlArray.Length];
for (int i = 0; i < urlArray.Length; i++)
Thread.Sleep(1000);
Console.WriteLine("i = 0", i);
Task task = new Task(() => returnedArray[i] = Download(urlArray[i], toPathArray[i], login, pass, getExt, true); );
task.Start();
taskArray[i] = task;
Task.WaitAll(taskArray);
Thread.Sleep(1000);
Console.WriteLine();
Console.WriteLine("Done! Press Enter to close.");
Console.ReadLine();
return returnedArray;
catch(Exception e)
Console.WriteLine();
Console.WriteLine(e.Message);
Console.ReadLine();
return null;
还有例外:
指向这条线:
我知道我错过了一些愚蠢的事情,但我正在努力解决这个问题。提前感谢您的帮助!
【问题讨论】:
在最后一次迭代中,当i
为 9 时,您运行任务 task.Start();
,并且很有可能在迭代结束后工作,i++
工作,在这种情况下,您的 i
将变为 @ 987654332@
制作i
的本地副本以在 lambda 中使用。直到循环完成后,您的 lambda 才会执行,此时 i = 10 - 对于 lambda 的所有十个副本。
@jdweng i < a.Length
是正确的。如果a.Length == 10
,i
永远不会超过 9。你在想<=
。
@S.Petrosov 它很可能出现在 all 迭代中。循环将很快完成......将任务调度到 ThreadPool(或其他任何地方)可能需要更长的时间。
那些Thread.Sleep
电话让我很痒。
【参考方案1】:
@Backs 的回答是正确的。有趣的是,在.Net 的最新版本中,如果您使用foreach
,那么循环变量将被关闭。所以,你可以:
foreach(var i in Enumerable.Range(0, urlArray.Length))
... new Task(() => returnedArray[i] = ...
无需复制。
【讨论】:
【参考方案2】:看起来您将数组过冲了 1,因为您计算循环中数组的长度,即 10,而数组从 0 变为 9。
for (int i = 0; i < urlArray.Length; i++)
应该是
for (int i = 0; i < urlArray.Length - 1; i++)
【讨论】:
【参考方案3】:看起来像Access to Modified Closure 问题。
复制i
到局部变量:
for (int i = 0; i < urlArray.Length; i++)
int index = i;
Thread.Sleep(1000);
Console.WriteLine("i = 0", index );
Task task = new Task(() => returnedArray[index] = Download(urlArray[index], toPathArray[index], login, pass, getExt, true); );
task.Start();
taskArray[index] = task;
【讨论】:
谢谢。就是这样。我只是在索引中添加了一个本地 int 并在循环中使用它以上是关于C# - 在for循环中使用相同的列表大小,索引超出了数组的范围[重复]的主要内容,如果未能解决你的问题,请参考以下文章