我想使用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);
}
}
答案 0 :(得分: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()
}
答案 1 :(得分:1)
编写代码的方式是,所有调用downloadScheduleFile的线程都引用了包含块中定义的相同2个变量。你应该做的是给每个线程一组自己的变量。
答案 2 :(得分:-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()
}
但试一试,因为你可能会遇到同样的问题......