我如何使用backgroundworker并以正确的方式向progressBar报告?

时间:2012-09-12 04:32:12

标签: c#

在这种情况下,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);

1 个答案:

答案 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 );