我正在使用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后重置)。
我觉得这两种方法都很笨拙,真的有一种更好的办法是以某种方式处理这两件事(在不同的线程上运行?)
答案 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
检查正确的页面是否已加载,您可以使其更加复杂。