2016-12-30 64 views
0

我想报告百分比的进度,并通过文本告诉用户像“建筑地图请稍候...”我如何报告另一班的背景工作人员?

在form1我有所有backgroundworker1事件。并且已经将WorkerReportsProgress设置为true,并且将WorkerSupportsCancellation设置为true。

我从工具箱中将它添加到设计器中的背景工作器。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      if (backgroundWorker1.CancellationPending == true) 
      { 
       e.Cancel = true; 
       return; // this will fall to the finally and close everything  
      } 
      else 
      { 
       ExtractImages ei = new ExtractImages(); 
       ei.Init(); 
      } 
     } 

     private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 

     } 

     private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 

     } 

和类报告来自:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.IO; 
using System.Net; 
using System.Xml; 
using HtmlAgilityPack; 

namespace SatelliteImages 
{ 
    class ExtractImages 
    { 
     static WebClient client; 
     static string htmltoextract; 
     public static List<string> countriescodes = new List<string>(); 
     public static List<string> countriesnames = new List<string>(); 
     public static List<string> DatesAndTimes = new List<string>(); 
     public static List<string> imagesUrls = new List<string>(); 
     static string firstUrlPart = "http://www.sat24.com/image2.ashx?region="; 
     static string secondUrlPart = "&time="; 
     static string thirdUrlPart = "&ir="; 

     public void Init() 
     { 
      ExtractCountires(); 
      foreach (string cc in countriescodes) 
      { 
       ExtractDateAndTime("http://www.sat24.com/image2.ashx?region=" + cc); 
      } 
      ImagesLinks(); 
     } 

     public static void ExtractCountires() 
     { 
      try 
      { 
       htmltoextract = "http://sat24.com/en/?ir=true";//"http://sat24.com/en/";// + regions; 
       client = new WebClient(); 
       client.DownloadFile(htmltoextract, @"c:\temp\sat24.html"); 
       client.Dispose(); 

       string tag1 = "<li><a href=\"/en/"; 
       string tag2 = "</a></li>"; 

       string s = System.IO.File.ReadAllText(@"c:\temp\sat24.html"); 
       s = s.Substring(s.IndexOf(tag1)); 
       s = s.Substring(0, s.LastIndexOf(tag2) + tag2.ToCharArray().Length); 
       s = s.Replace("\r", "").Replace("\n", "").Replace(" ", ""); 

       string[] parts = s.Split(new string[] { tag1, tag2 }, StringSplitOptions.RemoveEmptyEntries); 


       string tag3 = "<li><ahref=\"/en/"; 

       for (int i = 0; i < parts.Length; i++) 
       { 
        if (i == 17) 
        { 
         //break; 
        } 
        string l = ""; 
        if (parts[i].Contains(tag3)) 
         l = parts[i].Replace(tag3, ""); 

        string z1 = l.Substring(0, l.IndexOf('"')); 
        if (z1.Contains("</ul></li><liclass=")) 
        { 
         z1 = z1.Replace("</ul></li><liclass=", "af"); 
        } 
        countriescodes.Add(z1); 
        countriescodes.GroupBy(n => n).Any(c => c.Count() > 1); 

        string z2 = parts[i].Substring(parts[i].LastIndexOf('>') + 1); 
        if (z2.Contains("&amp;")) 
        { 
         z2 = z2.Replace("&amp;", " & "); 
        } 
        countriesnames.Add(z2); 
        countriesnames.GroupBy(n => n).Any(c => c.Count() > 1); 
       } 
      } 
      catch (Exception e) 
      { 

      } 
     } 

     public void ExtractDateAndTime(string baseAddress) 
     { 
      try 
      { 
       var wc = new WebClient(); 
       wc.BaseAddress = baseAddress; 
       HtmlDocument doc = new HtmlDocument(); 

       var temp = wc.DownloadData("/en"); 
       doc.Load(new MemoryStream(temp)); 

       var secTokenScript = doc.DocumentNode.Descendants() 
        .Where(e => 
          String.Compare(e.Name, "script", true) == 0 && 
          String.Compare(e.ParentNode.Name, "div", true) == 0 && 
          e.InnerText.Length > 0 && 
          e.InnerText.Trim().StartsWith("var region") 
         ).FirstOrDefault().InnerText; 
       var securityToken = secTokenScript; 
       securityToken = securityToken.Substring(0, securityToken.IndexOf("arrayImageTimes.push")); 
       securityToken = secTokenScript.Substring(securityToken.Length).Replace("arrayImageTimes.push('", "").Replace("')", ""); 
       var dates = securityToken.Trim().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); 
       var scriptDates = dates.Select(x => new ScriptDate { DateString = x }); 
       foreach (var date in scriptDates) 
       { 
        DatesAndTimes.Add(date.DateString); 
       } 
      } 
      catch 
      { 
       countriescodes = new List<string>(); 
       countriesnames = new List<string>(); 
       DatesAndTimes = new List<string>(); 
       imagesUrls = new List<string>(); 
       this.Init(); 
      } 
     } 

     public class ScriptDate 
     { 
      public string DateString { get; set; } 
      public int Year 
      { 
       get 
       { 
        return Convert.ToInt32(this.DateString.Substring(0, 4)); 
       } 
      } 
      public int Month 
      { 
       get 
       { 
        return Convert.ToInt32(this.DateString.Substring(4, 2)); 
       } 
      } 
      public int Day 
      { 
       get 
       { 
        return Convert.ToInt32(this.DateString.Substring(6, 2)); 
       } 
      } 
      public int Hours 
      { 
       get 
       { 
        return Convert.ToInt32(this.DateString.Substring(8, 2)); 
       } 
      } 
      public int Minutes 
      { 
       get 
       { 
        return Convert.ToInt32(this.DateString.Substring(10, 2)); 
       } 
      } 
     } 

     public void ImagesLinks() 
     { 
      int cnt = 0; 
      foreach (string countryCode in countriescodes) 
      { 
       cnt++; 
       for (; cnt < DatesAndTimes.Count(); cnt++) 
       { 
        string imageUrl = firstUrlPart + countryCode + secondUrlPart + DatesAndTimes[cnt] + thirdUrlPart + "true"; 
        imagesUrls.Add(imageUrl); 
        if (cnt % 10 == 0) break; 
       } 
      } 
     } 
    } 
} 

在我想,从init()它的工作每个国家的名义报告类。因此,例如,在标签上的form1上,它将报告当前处于Init环境中的哪个国家/地区的进展情况。然后,在与国家/地区编写完成时继续报告相同的标签标签上的东西,如“建立地图链接,请稍候...”

而这一切都报告给后台工作进度条progress progress事件作为整体工作。从0到100%。

这是完整的form1代码。今天,我使用webclient事件来下载和报告图像的进展情况。所以也许不知怎的,我应该使用它与班级,而不是背景工作?或者使用任务异步并等待?不确定。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.IO; 
using System.Net; 
using System.Threading; 
using System.Diagnostics; 

namespace SatelliteImages 
{ 
    public partial class Form1 : Form 
    { 
     WebClient webClient;    // Our WebClient that will be doing the downloading for us 
     Stopwatch sw = new Stopwatch(); // The stopwatch which we will be using to calculate the download speed 
     int count = 0; 
     PictureBoxBigSize pbbs; 

     public Form1() 
     { 
      InitializeComponent(); 

      backgroundWorker1.RunWorkerAsync(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 

     } 

     private void btnDownload_Click(object sender, EventArgs e) 
     { 
      //DownloadFile(ExtractImages.imagesUrls[count], @"C:\Temp\TestingSatelliteImagesDownload\" + count + ".jpg"); 
      // http://download.thinkbroadband.com/1GB.zip 
      DownloadFile("http://download.thinkbroadband.com/1GB.zip", @"C:\Temp\TestingSatelliteImagesDownload\" + "1GB.zip"); 
     } 

     public void DownloadFile(string urlAddress, string location) 
     { 
      using (webClient = new WebClient()) 
      { 
       webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed); 
       webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged); 

       // The variable that will be holding the url address (making sure it starts with http://) 
       Uri URL = urlAddress.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ? new Uri(urlAddress) : new Uri("http://" + urlAddress); 

       // Start the stopwatch which we will be using to calculate the download speed 
       sw.Start(); 
       //Thread.Sleep(50); 
       txtFileName.Text = count + ".jpg"; 
       try 
       { 
        // Start downloading the file 
        webClient.DownloadFileAsync(URL, location); 
       } 
       catch (Exception ex) 
       { 
        MessageBox.Show(ex.Message); 
       } 
      } 
     } 

     // The event that will fire whenever the progress of the WebClient is changed 
     private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e) 
     { 
      // Calculate download speed and output it to labelSpeed. 
      Label2.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. 
      Label4.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 
      Label5.Text = string.Format("{0} MB's/{1} MB's", 
       (e.BytesReceived/1024d/1024d).ToString("0.00"), 
       (e.TotalBytesToReceive/1024d/1024d).ToString("0.00")); 
     } 

     // The event that will trigger when the WebClient is completed 
     private void Completed(object sender, AsyncCompletedEventArgs e) 
     { 
      // Reset the stopwatch. 
      sw.Reset(); 

      if (e.Cancelled == true) 
      { 
       MessageBox.Show("Download has been canceled."); 
      } 
      else 
      { 

       count++; 
       DownloadFile(ExtractImages.imagesUrls[count], @"C:\Temp\TestingSatelliteImagesDownload\" + count + ".jpg"); 
      } 
     } 

     private void pictureBox1_MouseEnter(object sender, EventArgs e) 
     { 
      // 845, 615 
      pbbs = new PictureBoxBigSize(); 
      pbbs.GetImages(pictureBox1); 
      pbbs.Show(); 
     } 

主要目标是率先做出了一流的工作进展和关于它目前正在国家名称和全面进步创造了地图和链接报告一切到Form1进度和标签/秒。然后报告每个文件下载。因此现在使用webclient正在很好地报告每个图像的下载。但是,我不知道如何将它与form1结合起来。

+1

BGW已过时。你应该使用任务,而'IProgress '类来报告进度 –

回答

0

要从你必须调用backgroundWorker1.ReportProgress(...);

,并提供适当ProgressChangedEventArgs后台工作报告进度。

您的班级ExtractImages实际上与后台工作无关。它的目的是提取图像,我认为它不应该让后台工作人员作为参数来进行上述调用。相反,我建议给它一个事件本身提出时,它已经取得了进展:

class ExtractImages 
{ 
    // shortened 

    // inherit some EventArgs 
    public class ProgressEventArgs : EventArgs 
    { 
     public int Percentage {get;set;} 
     public string StateText {get;set;} 
    } 

    public event EventHandler<ProgressEventArgs> ProgressChanged; 

    public void Init() 
    { 
     ExtractCountires(); 
     foreach (string cc in countriescodes) 
     { 
      // raise event here 
      ProgressChanged?.Invoke(new ProgressChangedEventArgs {Percentage = ..., StateText = cc}); 
      ExtractDateAndTime("http://www.sat24.com/image2.ashx?region=" + cc); 
     } 
     ImagesLinks(); 
    } 
} 

,并在您DoWork方法订阅该事件:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    if (backgroundWorker1.CancellationPending == true) 
    { 
     e.Cancel = true; 
     return; // this will fall to the finally and close everything  
    } 
    else 
    { 
     ExtractImages ei = new ExtractImages(); 
     ei.ProgressChanged += (sender, e) => backgroundWorker1.ReportProgress(e.Percentage, e); 
     ei.Init(); 
    } 
} 

ProgressEventArgs可以把你需要的所有状态信息。 ReportProgress的第二个参数将成为backgroundWorker1_ProgressChanged处理程序的ProgressChangedEventArgs中的UserState属性。


的另一种方法是使用IProgress<T>接口和Progress<T>类并传递一个Progress<ProgressChangedArgs>实例作为参数传递给Init()

+0

Reneve我试过,并得到了一些erorrs,所以我不得不尝试修复它们。在form1中,我不得不改变这一行:ei.ProgressChanged + =(senders,ee)=> backgroundWorker1.ReportProgress(ee.Percentage,ee);它是发件人和e,但那些已经存在的dowork,所以我不得不改变发件人和ee。 –

+0

在这一行中:ProgressChanged?.DynamicInvoke(新的ProgressEventArgs {Percentage = 0,StateText = cc});这是Invoke,但我得到错误的视觉工作室建议我通过将其更改为DynamicInvoke并且百分比是= ...所以我不知道是什么改变它,所以我加了0.这三点给错误。 –

+0

但是,在运行程序时,它对progressBar1执行任何操作。在backgroundworker progresschanged事件中,我做了:ProgressBar1.Value = e.ProgressPercentage;但没有任何变化。 –

相关问题