Использование веб-браузера с Control.invoke - PullRequest
2 голосов
/ 29 марта 2011

Я занимаюсь разработкой приложения для Windows для очистки веб-страниц.Для этого я использую элемент управления Webbrowser - я не могу использовать классы webrequest / webclient / webresponse, потому что веб-страницы загружаются динамически с использованием JavaScript.Приложение работает нормально, но, поскольку я выполняю большую обработку, оно загружает пользовательский интерфейс без необходимости.Я получаю сообщение «не отвечает» с перерывами.Итак, что я сделал, это:1. Создайте веб-браузер в потоке пользовательского интерфейса2. Поместите длительные процессы в фоновый поток3. Всякий раз, когда мне нужно получить документ страницы, я использую Control.Invoke.4. Верните документ страницы с помощью вызова invoke в фоновый потокВ функции обратного вызова я вижу, что документ страницы извлекается нормально.Однако документ (HtmlDocument), возвращаемый фоновому работнику, не оценивается правильно.Когда я перехожу через отладчик, я получаю сообщение «Тайм-аут оценки функции ...».Я поиграл с синтаксисом и продолжаю получать недопустимое исключение приведения или кросс-потоковое исключение.Ниже показано, как я кодировал обратный вызов / делегат:

private delegate HtmlDocument RefreshDelegate(); 
private HtmlDocument RefreshBrowser()
    {
        WebBrowser br1 = ((WebBrowser)this.Controls["br1"]); //get webbrowser, "br1"
        br1.Refresh(); //refresh browser
        return br1.Document; //is retrieved correctly
   }

Теперь для кода в фоновом рабочем, который обрабатывает «возвращенный» HTMLDocument:

WebBrowser br1 = ((WebBrowser)this.Controls["br1"]); //get the browser
HtmlDocument document = (HtmlDocument)br1.Invoke(new RefreshDelegate(this.RefreshBrowser));  //not evaluated 
//do stuff with document

Обнаружено сообщение отладчика: "Оценка функции отключена, поскольку истек срок ожидания предыдущей оценки функции. Вы должны продолжить выполнение до возобновления оценки функции." .Это правильный способ решить эту проблему?Как я уже сказал, я не могу получить содержимое javascript с помощью веб-запроса и т. Д., Я также не могу запустить синтаксический анализ htmldocument в пользовательском интерфейсе, поскольку это приводит к ухудшению работы пользователя.Кроме того, бывает, что мне нужно создать несколько экземпляров веб-браузера.Если это не лучший способ, я открыт и для других библиотек.Спасибо.

Ответы [ 2 ]

2 голосов
/ 29 марта 2011

Это происходит потому, что методы WebBrowser, которые вы вызываете в рабочем потоке или в потоке отладчика, на самом деле не работают в этом потоке.WebBrowser - это COM-компонент с многопоточным подключением, COM автоматически отправляет вызовы от рабочего обратно в поток пользовательского интерфейса.Это не очень хорошо работает в отладчике, потому что поток пользовательского интерфейса заморожен отладчиком.

Ничего не поделаешь, фактически выполнение этих вызовов в потоке пользовательского интерфейса все еще оставляет вас открытыми для зависания пользовательского интерфейса.Единственное лекарство от этого - полностью отключить браузер в своем потоке STA.Вы не можете смотреть на это, не должно быть проблемой, которую я представляю.Проверьте этот ответ для кода, который вам нужен.

1 голос
/ 29 марта 2011

Я бы предложил использовать HtmlAgilityPack. Это специально разработано для веб-"слом".

http://htmlagilitypack.codeplex.com/

...