在这种情况下,progressBar移动速度快于真正的Dowork进度,然后在progressChanged事件中抛出异常,其中progressBar值超过100%,那么这里有什么错误,我如何以正确的方式计算和报告?
private List<string> webCrawler(string url, int levels , DoWorkEventArgs eve)
{
bool already = false;
HtmlAgilityPack.HtmlDocument doc;
HtmlWeb hw = new HtmlWeb();
List<string> webSites;// = new List<string>();
List<string> csFiles = new List<string>();
csFiles.Add("temp string to know that something is happening in level = " + levels.ToString());
csFiles.Add("current site name in this level is : " + url);
try
{
doc = hw.Load(url);
webSites = getLinks(doc);
if (levels == 0)
{
return csFiles;
}
else
{
int actual_sites = 0;
for (int i = 0; i < webSites.Count() && i < 20; i++) {
if ((worker.CancellationPending == true))
{
eve.Cancel = true;
break;
}
else
{
string t = webSites[i];
if ((t.StartsWith("http://") == true) || (t.StartsWith("https://") == true)) // replace this with future FilterJunkLinks function
{
for (int e = 0; e < csFiles.Count; e++)
{
if (csFiles[e].Contains(t))
{
already = true;
}
}
if (!already)
{
actual_sites++;
csFiles.AddRange(webCrawler(t, levels - 1,eve));
this.Invoke(new MethodInvoker(delegate { Texts(richTextBox1, "Level Number " + levels + " " + t + Environment.NewLine, Color.Red); }));
worker.ReportProgress(i * 10);
}
}
}
}
return csFiles;
}
}
catch
{
return csFiles;
}
}
public void Texts(RichTextBox box, string text, Color color)
{
box.SelectionStart = box.TextLength;
box.SelectionLength = 0;
box.SelectionColor = color;
box.AppendText(text);
box.SelectionColor = box.ForeColor;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
worker = sender as BackgroundWorker;
webCrawler(guys, 2,e);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
我在DoWork事件中传递了DoWorkEventsArgs的变量e,因此如果我需要取消操作,我可以在webCrawler函数中使用worker变量。在webCrawler中我称之为DoWorkEventArgs前夕。
问题是对progressBar的报告不是正确的方法。
将reportprogress视为:
for (int i = 0; i < webSites.Count() && i < 20; i++) {
double incPercent = (1 / webSites.Count());
if ((worker.CancellationPending == true))
{
eve.Cancel = true;
break;
}
else
{
string t = webSites[i];
if ((t.StartsWith("http://") == true) || (t.StartsWith("https://") == true)) // replace this with future FilterJunkLinks function
{
for (int e = 0; e < csFiles.Count; e++)
{
if (csFiles[e].Contains(t))
{
already = true;
}
}
if (!already)
{
actual_sites++;
csFiles.AddRange(webCrawler(t, levels - 1,eve));
this.Invoke(new MethodInvoker(delegate { Texts(richTextBox1, "Level Number " + levels + " " + t + Environment.NewLine, Color.Red); }));
worker.ReportProgress(i * (int)incPercent);
答案 0 :(得分:0)
worker.ReportProgress(i * 10);
任何时候你有我&gt; 10(即超过10页),您在进度条中的比例超过100%。
如果你真的想按百分比来做,我会做这样的事情:
double incPercent = (1 / webSites.Count())
.
.
.
.
worker.ReportProgress(i * incPercent );
作为旁注,您的变量名称和间距似乎有点偏离
编辑:对不起,当执行两个数字的除法并且您希望结果为double时,您必须确保除数或被除数是double类型。否则,您正在有效地执行int / int,这会返回一个int。您可能知道,int会截断您的小数点。这就是你在计算中得零的原因。
此外,reportProgress方法取0到100之间的值,因此您必须将最终结果乘以100.
修复你的代码:
double incPercent = (1 / (double)webSites.Count())
.
.
.
.
worker.ReportProgress(i * incPercent * 100 );