我试图同时下载两个文件,不知何故,我得到了一个“索引超出了数组的界限”。
var downloadthread1 = new FileDownload();
var downloadthread2 = new FileDownload();
downloadthread1.DownloadProgressChanged += DownloadProgressChanged;
downloadthread1.DownloadCompleted += DownloadCompleted;
downloadthread2.DownloadProgressChanged += DownloadProgressChanged;
downloadthread2.DownloadCompleted += DownloadCompleted;
Task.Factory.StartNew(() => downloadthread1.Start(downloadDataGridView.Rows[0].Cells[1].Value.ToString(), 0));
Task.Factory.StartNew(() => downloadthread2.Start(downloadDataGridView.Rows[1].Cells[1].Value.ToString(), 1));
Task.WaitAll();这个部分可以工作,但是当我在循环中这样做时,它似乎不起作用:
FileDownload[] fileDownloads = new FileDownload[2];
fileDownloads[0] = new FileDownload();
fileDownloads[1] = new FileDownload();
for (int i = 0; i < 2; i++)
{
fileDownloads[i].DownloadProgressChanged += DownloadProgressChanged;
fileDownloads[i].DownloadCompleted += DownloadCompleted;
fileDownloads[i].m_UrlQueue.Enqueue(m_Downloader.m_UrlQueue.Dequeue());
string downloadPath = downloadDataGridView.Rows[i].Cells[1].Value.ToString();
Task.Factory.StartNew(() => fileDownloads[i].Start(downloadPath, i));
}正如ReSharper所指出的,这可能是一个叫做“访问修改的闭包”的问题,除了我不改变i索引这一事实之外,这似乎就是问题所在。
我必须在线程中使用索引,以便更新DataGridView中的DownloadProgressChanged并完成。
发布于 2017-04-16 07:27:22
Resharpes建议您不要在for循环中使用变量i。您必须创建新变量并将i分配给它,然后在循环中使用新变量。
演示这个概念的一些基本代码:
for (int i = 0; i < 10; i++)
{
new Thread(() => Console.Write(i)).Start();
}这可能不会打印0123456789,因为当您同时运行多个线程并使用全局变量时,thread5可能会访问i而不是thread6。
要解决这个问题,我们必须这样做:
for (int i = 0; i < 10; i++)
{
int temp = i;
new Thread(() => Console.Write(temp)).Start();
}因为temp不是全局变量,而是每个线程的本地变量,所以不会出现问题,输出将始终是0123456789。
https://stackoverflow.com/questions/43434728
复制相似问题