I have this code:
int countfiletodownload = 0;
bool processStatus = false;
private void Parseanddownloadfiles()
{
downloadhtml(mainurl);
if (bgw.CancellationPending == false)
{
backgroundWorker1.ReportProgress(0, "Parsing Links");
HtmlAgilityPack.HtmlWeb hw = new HtmlAgilityPack.HtmlWeb();
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc = hw.Load(path_exe + "\\page.html");
foreach (HtmlAgilityPack.HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]"))
{
string hrefValue = link.GetAttributeValue("href", string.Empty);
if (hrefValue.Contains("US"))
{
string url = "http://www.mytests.com;
parsedlinks.Add(url);
if (bgw.CancellationPending == true)
return;
}
}
countfiletodownload = parsedlinks.Count;
backgroundWorker1.ReportProgress(0, "Downloading Files");
processStatus = true;
for (int i = 0; i < parsedlinks.Count && bgw.CancellationPending == false; i++)
{
try
{
using (WebClient client = new WebClient())
{
client.DownloadFileCompleted += client_DownloadFileCompleted;
client.DownloadProgressChanged += client_DownloadProgressChanged;
sw.Start();
Uri uri = new Uri(parsedlinks[i]);
string filename = parsedlinks[i].Substring(71);
client.DownloadFileAsync(uri, filesdirectory + "\\" + filename);
string filenametoreport = filename.Substring(1);
countfiletodownload--;
backgroundWorker1.ReportProgress(countfiletodownload, filenametoreport);
}
}
catch (Exception err)
{
string error = err.ToString();
}
}
}
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
// Calculate download speed and output it to labelSpeed.
label12.Text = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));
// Update the progressbar percentage only when the value is not the same.
progressBar1.Value = e.ProgressPercentage;
// Show the percentage on our label.
label13.Text = e.ProgressPercentage.ToString() + "%";
// Update the label with how much data have been downloaded so far and the total size of the file we are currently downloading
label14.Text = string.Format("{0} MB's / {1} MB's",
(e.BytesReceived / 1024d / 1024d).ToString("0.00"),
(e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00"));
}
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
// Reset the stopwatch.
sw.Reset();
if (e.Cancelled == true)
{
MessageBox.Show("Download has been canceled.");
}
else
{
MessageBox.Show("Download completed!");
}
}
I'm registering two events of the WebClient, DownloadFileCompleted and DownloadProgressChanged.
The method Parseanddownloadfiles() is being called from the backgroundworker dowork event:
BackgroundWorker bgw;
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
bgw = (BackgroundWorker)sender;
if (bgw.CancellationPending == true)
{
return;
}
else
{
Parseanddownloadfiles();
}
}
Once I added the client two events, I was getting an exception in the client_DownloadProgressChanged event on the first line:
label12.Text = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));
Cross-thread operation not valid: Control 'label12' accessed from a thread other than the thread it was created on
How should I work around this exception?