您好我正在制作我的网络抓取工具,我需要一个递归函数,以毫秒为单位查看商品可用性。但我无法处理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();
}
如果我在程序中关闭正在运行的线程,它就会停止。
答案 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);
}
}