如何处理WebBrowser控件的线程

时间:2010-11-05 18:55:17

标签: c# multithreading webbrowser-control

我正在使用BrowserControl导航到网站上的网页范围,然后解析html并提取有关书籍等的信息......我遇到了与线程相关的问题(我认为)...

我有类似的东西。

// MAIN LOOP
for (int i = 0; i < NumberOfPages; i++)
 {
  WebBrowser.Navigate("http://AWebSite/" + NumberOfPages.ToString());
 }

// HANDLE ON_LOADED EVENT
 void WebBrowser_LoadCompleted(object sender, NavigationEventArgs e)
    {
   // Retrieve HTMLDocument, Parse it etc
    }

现在,由于在控件导航到某个页面后触发该事件需要几秒钟,因此我有两个选项之一:

OPTION1 在我的主循环中等待几秒钟,如下所示:

for (int i = 0; i < NumberOfPages; i++)
{
  WebBrowser.Navigate("http://www.mysite.com"); 

// wait for 5 seconds
DateTime wait = new DateTime();
while (new DateTime().Ticks < wait.Ticks + 5000)  
    {
     // not sure if I need do events here         
    }
}

OPTION2 另一个想法是将全局变量作为(布尔)标志向事件处理程序指示页面仍在下载(标志在主外观中设置为忙,然后重置,然后在处理返回的html后重置)。

我觉得这两种方法都很笨拙,真的有一种更好的办法是以某种方式处理这两件事(在不同的线程上运行?)

2 个答案:

答案 0 :(得分:1)

是的,延迟是笨拙的 - 可能需要更长时间或更长时间。

您需要WebBrowser控件吗?看起来你正在进行一些批处理。如果是这样,System.Net.WebClient可能适合您。它有阻塞和异步方法 - .DownloadData和.DoanloadDataAsync。

如果你需要,我可以挖出一些代码,但快速搜索会显示一些例子。

答案 1 :(得分:0)

你可以通过误解迭代器来实现这一点,正如我所描述的here

例如:

interface IAction { void Execute(Action callback); }

public static void ExecAction(IEnumerator<IAction> enumerator) {
    if (enumerator.MoveNext())
        enumerator.Current.Execute(() => ExecAction(enumerator));
}

class WaitForLoad : IAction {
    void IAction.Execute(Action callback) {
       //Handle the LoadCompleted event and call callback
    }
}

IEnumerator<IAction> YourMethod() { 
    ...
    for (int i = 0; i < NumberOfPages; i++) {
        WebBrowser.Navigate("http://AWebSite/" + NumberOfPages.ToString());
        yield return new WaitForLoad();
    }
    ...
}

通过WaitForLoad检查正确的页面是否已加载,您可以使其更加复杂。