Как обрабатывать потоки для элемента управления WebBrowser - PullRequest
1 голос
/ 05 ноября 2010

Я использую 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 ]

1 голос
/ 05 ноября 2010

Да, задержка неуклюжа - она ​​может занять больше времени или что-то в этом роде.

Вам нужен элемент управления WebBrowser? Похоже, что вы делаете некоторую пакетную обработку. Если это так, System.Net.WebClient может работать для вас. Он имеет блокирующие и асинхронные методы - .DownloadData и .DoanloadDataAsync.

Возможно, я могу выкопать некоторый код, если вам это нужно, но быстрый поиск покажет некоторые примеры.

0 голосов
/ 05 ноября 2010

Вы можете сделать это, неправильно введя итераторы, как я описал здесь .

Например:

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 проверив, что загружена правильная страница.

...