Daniel Lip
Daniel Lip

Reputation: 11321

How can i stop a recursive loop?

I mean not to pause and resume but to cancel/stop. To pause and resume I'm using this in the top of Form1 :

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

Then in the buttons im doing _busy.Reset(); and _busy.Set(); to pause and resume. But if I want to completly stop/cancel the recrusive loop?

This is the recursive loop code:

private List<string> test(string url, int levels,DoWorkEventArgs eve)
        {
            _busy.WaitOne();
            if (cancel == true)
            {

            }
            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, "Level: " + levels.ToString(), Color.Green); }));
                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))
                            {
                                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;
            }

        }

I have a button click event for the cancel/stop there I have a flag I set to true then in the recursive loop above I did:

if (cancel == true)
            {

            }

Tried to add break; but its not for or while so you cant use break;

How can I do it?

Thanks.

Upvotes: 0

Views: 3243

Answers (1)

DerApe
DerApe

Reputation: 3175

Okay I will post a complete answer :-)
The problem with recursive functions is, well, they are recursive. As long as you don't know when to quit it, it will run forever.
So what you need is a condition to finish it. Since the method is calling it self over and over again, you basically need to go up the call stack again and return somethin as you would normally do in any other method which should return something.
A small example is posted here So in order to exit your recursive loop you need a proper return statement and return what you need:

if (cancel)
{
  return new List<string>();
}

You obviously would put everything you need into your list ;-)

Upvotes: 1

Related Questions