alicanerdogan
alicanerdogan

Reputation: 1837

Unable to pass different string values to different threads

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

Answers (3)

Charleh
Charleh

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

mfeingold
mfeingold

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

Daniel A. White
Daniel A. White

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

Related Questions