0

我想通过使用 webclient 方法和同时运行的多个线程下载多个文件。我的 url 结构取决于变量“int i”,所以我使用 for 循环来生成 url 和文件路径。问题是在启动线程之前,url 和 filepath 值都会更改。时间线如下:

在主循环中,url = "url1" 和 path = "filepath1"。

使用值“url1”和“filepath1”调用 Thread1。

在主循环中,url = "url2" 和 path = "filepath2"。

使用值“url2”和“filepath2”调用 Thread2。

Thread1 以值“url2”和“filepath2”开头。

Thread2 以值“url2”和“filepath2”开头。

我找不到任何优雅的解决方案。你有什么建议?

string path = "";
string url = "";
string baseURL = "http://www.somewebsite.com/12/";
for (int i = 10; i <= DateTime.Now.Month; i++)
{
    path = "C:\\folder\\" + i.ToString() + ".html";
    url = baseURL + i.ToString();
    Thread webThread = new Thread(delegate()
    {
       downloadScheduleFile(url,path);
    });
    webThread.Start()
}

private void downloadScheduleFile(string url, string filepath)
{
    var client = new WebClient();
    try
    {
       client.DownloadFile(url, filepath);
    }
    catch(WebException e) {
       Console.WriteLine(System.Threading.Thread.CurrentThread.Name+e.Message);
    }
}
4

3 回答 3

2

这是因为当你的线程开始时,path并且url已经改变了。您必须创建更接近的本地副本。

string baseURL = "http://www.somewebsite.com/12/";
for (int i = 10; i <= DateTime.Now.Month; i++)
{
    string path = "C:\\folder\\" + i.ToString() + ".html"; // path declared here
    string url = baseURL + i.ToString(); // url declared here
    Thread webThread = new Thread(delegate()
    {
       downloadScheduleFile(url,path);
    });
    webThread.Start()
}
于 2012-11-29T19:12:35.850 回答
1

您编写代码的方式所有调用 downloadScheduleFile 的线程都引用了包含块中定义的相同 2 个变量。你应该做的是给每个线程它自己的一组变量。

于 2012-11-29T19:15:59.123 回答
-1

您需要在委托的外部范围内捕获变量,我很确定您可以这样做:

string path = "";
string url = "";
string baseURL = "http://www.somewebsite.com/12/";
for (int i = 10; i <= DateTime.Now.Month; i++)
{
    path = "C:\\folder\\" + i.ToString() + ".html";
    url = baseURL + i.ToString();
    Thread webThread = new Thread(delegate()
    {
       string innerPath = path;
       string innerUrl = url
       downloadScheduleFile(innerUrl,innerPath);
    });
    webThread.Start()
}

但是试一试,因为你可能会遇到同样的问题......

于 2012-11-29T19:16:53.300 回答