Reputation: 1837
I want to download more than one file by using webclient method and many threads running at the same time. My url structure depends on a variable 'int i', so i use a for loop to generate urls and filepaths. The problem is until the started thread is brought upon, the url and filepath values are changed. The timeline occurs as below:
In main loop, url = "url1" and path = "filepath1".
Thread1 is called with value "url1" and "filepath1".
In main loop, url = "url2" and path = "filepath2".
Thread2 is called with value "url2" and "filepath2".
Thread1 started with value "url2" and "filepath2".
Thread2 started with value "url2" and "filepath2".
I couldn't find any elegant solutions. What would you suggest?
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);
}
}
Upvotes: 0
Views: 85
Reputation: 14002
You need to capture the variables in the outer scope within the delegate, I'm pretty sure you can do this:
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()
}
But give it a try as you might end up with the same issue...
Upvotes: -1
Reputation: 7134
The way you code is written all threads calling the downloadScheduleFile are referencing the same 2 variables defined in the encompassing block. What you should do is to give every thread its own set of variables.
Upvotes: 1
Reputation: 191037
Its because by the time your thread starts, path
and url
have changed. You have to create closer local copies.
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()
}
Upvotes: 2