c#如何处理递归函数中的Stackoverflow异常

时间:2014-07-15 05:22:48

标签: c# selenium recursion stack-overflow

您好我正在制作我的网络抓取工具,我需要一个递归函数,以毫秒为单位查看商品可用性。但我无法处理stackoverflow异常,因为我一直在调用viewoffers()函数。请帮助:)

public void viewoffers(IWebDriver driver, string user, string pass)
    {
            Thread.Sleep(timespan);

            try { int c = driver.WindowHandles.Count; }
            catch { AbortThread(user); }

            driver.Navigate().GoToUrl("https://as.realtrans.com/webtop/orders/offers/offer_order_viewInfo.asp?user=" + user);

            try { int c = driver.WindowHandles.Count; }
            catch { AbortThread(user); }

            if (driver.Url.ToString().Contains("offer_order_viewInfo.asp?user="))
            {

                try { int c = driver.WindowHandles.Count; }
                catch { AbortThread(user); }

                if (driver.PageSource.Contains("id=\"chkOffer\""))
                {
                    driver.FindElement(By.Id("chkOffer")).Click();
                    driver.FindElement(By.ClassName("CellClass")).FindElement(By.TagName("a")).Click();
                    driver.FindElement(By.Name("btnSubmit")).Click();
                }


                this.viewoffers(driver, user, pass);

            }
            else
            {
                this.reopenaccount(driver, user, pass);

            }
    }


    public void AbortThread(string username)
    {
        RunningAccounts ra = runningAccounts.Find(item => item.account.username == username);
        runningAccounts.Remove(ra);
        threadsList.Remove(ra.thread);
        ra.thread.Abort();

    }

如果我在程序中关闭正在运行的线程,它就会停止。

1 个答案:

答案 0 :(得分:1)

唉,递归和堆栈。遗憾的是,这里的解决方案是以不使用递归的方式编写代码。请记住,永远不需要递归。作为计算机科学的一般规则,如果你可以用递归来编写它,你可以用循环来编写它。它只不过是一个捷径,虽然是一个非常好的捷径(直到它溢出)。但如果你在一个循环中这样做,那应该可以解决你所有的问题,并且在资源方面更轻松。

我显然没有对此进行过测试,而且它使用的是while (true),我通常认为这是一种不好的做法,但这里有一个例子可以说明这种转换背后的理论:

public void viewoffers(IWebDriver driver, string user, string pass)
{
    while (true)
    {
        Thread.Sleep(timespan);

        try { int c = driver.WindowHandles.Count; }
        catch { AbortThread(user); }

        driver.Navigate().GoToUrl("https://as.realtrans.com/webtop/orders/offers/offer_order_viewInfo.asp?user=" + user);

        try { int c = driver.WindowHandles.Count; }
        catch { AbortThread(user); }

        if (driver.Url.ToString().Contains("offer_order_viewInfo.asp?user="))
        {
            try { int c = driver.WindowHandles.Count; }
            catch { AbortThread(user); }

            if (driver.PageSource.Contains("id=\"chkOffer\""))
            {
                driver.FindElement(By.Id("chkOffer")).Click();
                driver.FindElement(By.ClassName("CellClass")).FindElement(By.TagName("a")).Click();
                driver.FindElement(By.Name("btnSubmit")).Click();
            }
        }
        else
        {
            break;
        }
    }

    this.reopenaccount(driver, user, pass);
}

}