How to Handle Threading for WebBrowser Control

半腔热情 提交于 2020-01-16 05:46:12

问题


I am using BrowserControl to navigate to range of web pages on a site and then parse the html and extract information about books etc… I am having problems related (I think) to threading…

I have something like this.

// 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
    }

Now since it takes a few seconds for the event to fire after the control navigates to a page, I have one of two options:

OPTION1 Wait a few seconds in my main loop, like this:

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 Another idea is to a Global Variable as a (Boolean) Flag to indicate to the event handler that the page is still downloading (the flag is set to busy in the main look and then reset and then reset after after handling the html returned).

I have a feeling both of these approaches are clumsy and really that there is a better way is to somehow handle these two things (running on different threads?)


回答1:


Yeah, a delay is clumsy - it may take longer than that or whatever.

Do you need the WebBrowser control? It looks like you're doing some batch processing. If that's so, the System.Net.WebClient may work for you. It has blocking and asynchronous methods - .DownloadData and .DoanloadDataAsync.

I can probably dig up some code if you need it, but a quick search shows some examples out there.




回答2:


You can do this by misuing iterators, as I described here.

For example:

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();
    }
    ...
}

You can make this more sophisticated by having WaitForLoad check that the correct page has loaded.



来源:https://stackoverflow.com/questions/4109113/how-to-handle-threading-for-webbrowser-control

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!