调试时代码工作正常,但它在没有调试的情况下运行时不起作用

时间:2013-10-31 15:32:41

标签: c# html visual-studio-2010 debugging

  string entry = Titleentry.Text;
        webBrowser1.Navigate("http://www.bookdepository.com/search/advanced");

        //HtmlElementCollection bookCollection;

        while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
        {
            Application.DoEvents();
        }

        HtmlElementCollection bookCollection = webBrowser1.Document.GetElementsByTagName("input");
        foreach (HtmlElement curElement in bookCollection)
        {
            if ((curElement.GetAttribute("id").ToString() == "searchTitle"))
            {
                curElement.SetAttribute("value", entry);
            }
        }



        HtmlElementCollection filterCollection = webBrowser1.Document.GetElementById("filterSortBy").GetElementsByTagName("option");
        List<HtmlElement> filterList = new List<HtmlElement>();
        foreach (HtmlElement filterItem in filterCollection) { filterList.Add(filterItem); }
        HtmlElement filterElement =
          (HtmlElement)filterList.Where(filterOption => filterOption.GetAttribute("value").Equals("price_low_high", StringComparison.InvariantCultureIgnoreCase)).SingleOrDefault();

        if (filterElement.GetAttribute("value").Equals("price_low_high"))
        {
            filterElement.SetAttribute("Selected", "price_low_high");
            filterElement.InvokeMember("click");
        }

        bookCollection = webBrowser1.Document.GetElementsByTagName("button");

        foreach (HtmlElement curElement in bookCollection)
        {
            if (curElement.GetAttribute("id").Equals("searchSubmit"))
            {
                curElement.InvokeMember("click");
            }
        }
        while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
        {
            Application.DoEvents();
        }

        MessageBox.Show("Loaded");

        System.Timers.Timer myTimer = new System.Timers.Timer(5000);
        myTimer.Enabled = true;
        myTimer.Start();
        myTimer.Stop();

        if (webBrowser1.ReadyState == WebBrowserReadyState.Complete) //from here on the code doesnt work.
        {
            HtmlElementCollection avCollection = webBrowser1.Document.GetElementById("filterAvailability").GetElementsByTagName("option");

            List<HtmlElement> avList = new List<HtmlElement>();
            foreach(HtmlElement avItem in avCollection)
            {
                avList.Add(avItem);
            }

            HtmlElement avElement =
                (HtmlElement)avList.Where(avOption => avOption.GetAttribute("value").Equals("1")).SingleOrDefault();

            if (avElement.GetAttribute("value").Equals("1"))
            {
                avElement.SetAttribute("Selected", "1");
                avElement.InvokeMember("click");
            }

            bookCollection = webBrowser1.Document.GetElementsByTagName("button");
            foreach (HtmlElement curElement in bookCollection)
            {
                if (curElement.GetAttribute("id").Equals("searchSubmit"))
                {
                    curElement.InvokeMember("click");
                }
            }
        }

这是整个代码。我尝试用计时器思考设置延迟,因为它反应太快但计时器也没有工作,所以我不确定问题是什么。

不起作用的代码假设创建具有3个计数的avList并选择值1.值1表示网站的库存可用性。

在没有调试的情况下运行时,它似乎完全忽略了if条件中写的代码。

感谢

1 个答案:

答案 0 :(得分:1)

好的,问题在于您设置代码的方式。你试图一个接一个地做事,这会产生一些奇怪的结果。最好允许API(WebBrowser)告诉您发生了什么,而不是在完成之前尝试查询它。

有一个循环检查“你还没完成?”被认为是后台练习,因为它会阻塞你的代码并占用处理器浪费的等待循环。

您需要做的是查看WebBrowser API的文档,并弄清楚WebBrowser如何与调用类进行通信。 C#占据了Events和Delgates的巨大优势,因此我的建议是查看是否存在您正在寻找的事件。快速搜索出现了:

http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.ondocumentcompleted.aspx

除了旋转while循环直到条件满足之外,这是一种可移动的可控方法。让API在完成后通知您,然后您可以决定如何处理它。至于您的活动,以下是该活动如何连线的示例:

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.onkeydown.aspx

因此您不必在循环中检查它们,从而耗费处理时间。

此外,由于您在.NET世界中可以访问linq。你不必写出你的循环来找到一些东西。例如:

    //Note: I have not tested this code, but this is close to what it should look like
    bookCollection.where(x => x.GetAttribute("id").ToString() == "searchTitle")
              .ForEach(x => x.SetAttribute("value", entry));

我不能保证这有多快,但LINQ倾向于清理循环和搜索的逻辑。

=====================================

如果您坚持使用代码,问题就出现在

     webBrowser1.ReadyState

不再处于“完成”状态。但是,你的while循环已经在上面检查了这个条件,所以你可以删除IF语句。我告诉你,你有一个iffy while循环的原因是出于这个原因。枚举值是存在的,以便您可以在WebBrowser进程仍在处理时查询它。这在多线程软件中很有用。但是,我的猜测是该标志被翻转为

   webBrowser1.ReadyState == WebBrowserReadyState.Complete
在页面显示之前

。这可以解释为什么你的while循环接收并存在。现在,问题是它可能会将枚举转换为未初始化,因为它已完成加载页面并断开了套接字连接。这将使其进入未初始化状态。此API依赖于状态机模式,状态序列可能与您认为的不同。以下是有关状态机的更多信息:

Simple state machine example in C#?

我希望这有帮助!