2015-11-10 45 views
-2

我有这样的代码:如何使用backgroundworker dowork事件中的WebClient progresschanged事件?

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!"); 
    } 
} 

我注册的Web客户端的两个事件, DownloadFileCompleted和DownloadProgressChanged。

方法Parseanddownloadfiles()被从BackgroundWorker的DoWork的事件称为:

BackgroundWorker bgw; 
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    bgw = (BackgroundWorker)sender; 
    if (bgw.CancellationPending == true) 
    { 
     return; 
    } 
    else 
    { 
     Parseanddownloadfiles(); 
    } 
} 

一旦我增加了客户端的两个事件,我是在第一行中的client_DownloadProgressChanged事件得到一个例外:

label12.Text = string.Format("{0} kb/s", (e.BytesReceived/1024d/sw.Elapsed.TotalSeconds).ToString("0.00")); 

跨线程操作无效:从其创建的线程以外的线程访问的控件'label12'

我应该如何解决这个异常?

+2

[?如何更新从C#另一个线程的GUI(http://stackoverflow.com/questions/661561/how-to -update最GUI的从-另一个线程在-c)的 –

回答

0

要对UI元素进行跨线程调用,您可以设置并使用调用委托。这个例子只适用于一个标签。所有其他控件都必须有类似的方法。

//Create a delegate for the call 
public delegate void VoidStringDelegate(string str); 

public void UpdateLabel12(string LabelText) 
{ 
    if (!label12.InvokeRequired) 
    {//If on the same thread directly change the value 
     label12.Text = LabelText; 
    } 
    else 
    {//If on a separate thread make an invoke call to this method from the correct thread 
     label12.Invoke(new VoidStringDelegate(UpdateLabel12), LabelText); 
    } 
} 
0

改变 “有问题” 的行:

label12.BeginInvoke((Action)(() => label12.Text = string.Format("{0} kb/s", (e.BytesReceived/1024d/sw.Elapsed.TotalSeconds).ToString("0.00"))); 
相关问题