0

form1の上部に追加しました:

System.Threading.ManualResetEvent _busy = new System.Threading.ManualResetEvent(true);

また、form1の上部に2つのフラグを追加しました。

bool pause;
bool resume;

コンストラクターでは、両方のフラグがfalseに設定されています。

次に、再帰ループである関数があります。

private List<string> test(string url, int levels,DoWorkEventArgs eve)
        {
            if (pause == true)
            {
                _busy.Reset();
            }
            if (resume == true)
            {
                _busy.Set();
            }
            this.Invoke(new MethodInvoker(delegate { label3.Text = label3.Text = (Int32.Parse(label12.Text) + Int32.Parse(label10.Text)).ToString(); }));

            HtmlWeb hw = new HtmlWeb();
            List<string> webSites;
            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
            {
                this.Invoke(new MethodInvoker(delegate { ColorText.Texts(richTextBox1, "Loading The Url:   " , Color.Red); }));
                this.Invoke(new MethodInvoker(delegate { ColorText.Texts(richTextBox1, url + "...",Color.Blue); }));
                HtmlAgilityPack.HtmlDocument doc = TimeOut.getHtmlDocumentWebClient(url, false, "", 0, "", "");

                this.Invoke(new MethodInvoker(delegate { ColorText.Texts(richTextBox1, " Done " + Environment.NewLine, Color.Red); }));


                    currentCrawlingSite.Add(url);
                    webSites = getLinks(doc);
                    removeDupes(webSites);
                    removeDuplicates(webSites, currentCrawlingSite);
                    removeDuplicates(webSites, sitesToCrawl);
                    if (removeExt == true)
                    {
                       for (int i = 0; i < webSites.Count; i++)
                       {
                           webSites.Remove(removeExternals(webSites));
                       }
                    }
                    if (downLoadImages == true)
                    {
                        webContent.retrieveImages(url);                     }

                    if (levels > 0)
                        sitesToCrawl.AddRange(webSites
                    this.Invoke(new MethodInvoker(delegate { label7.Text = sitesToCrawl.Count.ToString(); }));
                    this.Invoke(new MethodInvoker(delegate { label12.Text = currentCrawlingSite.Count.ToString(); }));


                    if (levels == 0)
                    {
                        return csFiles;
                    }
                    else
                    {


                        for (int i = 0; i < webSites.Count(); i++)//&& i < 20; i++)                         {



                            string t = webSites[i];
                            if ((t.StartsWith("http://") == true) || (t.StartsWith("https://") == true)) // replace this with future FilterJunkLinks function
                            {
                                csFiles.AddRange(test(t, levels - 1, eve));                                
                            }

                        }
                        return csFiles;
                    }



            }
            catch
            {
                failedUrls++;
                this.Invoke(new MethodInvoker(delegate { label10.Text = failedUrls.ToString(); }));
                this.Invoke(new MethodInvoker(delegate { ColorText.Texts(richTextBox1, " Failed " + Environment.NewLine, Color.Green); }));
                return csFiles;
            }

        }

backgroundworker DoWorkイベントで、これを追加しました。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            _busy.WaitOne();
                this.Invoke(new MethodInvoker(delegate { label2.Text = "Website To Crawl: "; }));
                this.Invoke(new MethodInvoker(delegate { label4.Text = mainUrl; }));
                test(mainUrl, levelsToCrawl, e);
        }

次に、2つのボタンでイベントをクリックします。1つは一時停止用、もう1つは再開用です。

private void button4_Click(object sender, EventArgs e)
        {
            pause = true;
        }

        private void button5_Click(object sender, EventArgs e)
        {
            resume = true;
        }

しかし、ボタンの一時停止をクリックしても、再開ボタンでも何も起こりません。プロセスは継続しています。_busy.Reset();を作成するために、各ボタンにフラグを付けずに試しました。および_busy.Set(); しかし、何もありません。

私が欲しいのは、どういうわけか再帰ループを一時停止して再開することです。バックグラウンドワーカーに接続されているかどうかはわかりませんが、プロセスを一時停止して再開することをお勧めします。

私は何をすべきか ?

ありがとう。

4

1 に答える 1

1
   _busy.WaitOne();

これが、ワーカーを一時停止させるステートメントです。ただし、イベントがまだリセットされないDoWork()の開始時にのみ表示されます。ループ内に移動する必要があります。

まだ遭遇していない2番目のバグは、一時停止すると再開できないことです。ワーカーはもう実行されておらず、 resume変数に注意を払っていないためです。これらの変数を取り除くには、ClickイベントでSet()メソッドとReset()メソッドを直接呼び出す必要があります。

于 2012-10-18T08:24:47.710 に答える