首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多线程下载管理器和DataGridView

多线程下载管理器和DataGridView
EN

Stack Overflow用户
提问于 2017-04-16 07:12:52
回答 1查看 58关注 0票数 1

我试图同时下载两个文件,不知何故,我得到了一个“索引超出了数组的界限”。

代码语言:javascript
复制
            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();

这个部分可以工作,但是当我在循环中这样做时,它似乎不起作用:

代码语言:javascript
复制
            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并完成。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-16 07:27:22

Resharpes建议您不要在for循环中使用变量i。您必须创建新变量并将i分配给它,然后在循环中使用新变量。

演示这个概念的一些基本代码:

代码语言:javascript
复制
        for (int i = 0; i < 10; i++)
        {
            new Thread(() => Console.Write(i)).Start();
        }

这可能不会打印0123456789,因为当您同时运行多个线程并使用全局变量时,thread5可能会访问i而不是thread6。

要解决这个问题,我们必须这样做:

代码语言:javascript
复制
        for (int i = 0; i < 10; i++)
        {
            int temp = i;
            new Thread(() => Console.Write(temp)).Start();
        }

因为temp不是全局变量,而是每个线程的本地变量,所以不会出现问题,输出将始终是0123456789。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43434728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档