我想以百分比的形式报告进度,并通过文字告诉用户类似于"建筑地图请等待......"
在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("&"))
{
z2 = z2.Replace("&", " & ");
}
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()中的循环中当前正在工作的国家时的进展
然后,当标签上的国家/地区在标签上写下类似的标签时,请继续报告相同的标签;建立地图链接请等待......&#34;
所有这一切都要报告给后工作者progress *事件中的progressBar作为整体工作。从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 progressBar和label / s报告有关其当前正在处理的国家/地区名称以及创建地图和链接的总体进度的所有内容。然后报告每个文件下载。因此,现在使用webclient工作正常,报告每个图像的下载。但是在课堂上的第一个操作我不确定如何将它与form1结合起来。
答案 0 :(得分:1)
要报告后台工作人员的进度,您必须致电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
的第二个参数成为UserState
处理程序backgroundWorker1_ProgressChanged
中的ProgressChangedEventArgs
属性。
另一种方法是使用IProgress<T>
接口和Progress<T>
类,并将Progress<ProgressChangedArgs>
实例作为参数传递给Init()
。