WebBrowser.Navigated срабатывает только тогда, когда я MessageBox.Show();

StackOverflow https://stackoverflow.com/questions/369594

Вопрос

У меня есть элемент управления WebBrowser, экземпляр которого создается динамически из фонового потока STA, поскольку родительский поток является BackgroundWorker и имеет множество других задач.

Проблема в том, что событие Navigated никогда не срабатывает, пока я не вставлю MessageBox.Show() в метод, который сообщил об этом .Navigate().Я объясню:

ThreadStart ts = new ThreadStart(GetLandingPageContent_ChildThread);
Thread t = new Thread(ts);
t.SetApartmentState(ApartmentState.STA);
t.Name = "Mailbox Processor";
t.Start();

protected void GetLandingPageContent_ChildThread()
{
 WebBrowser wb = new WebBrowser();
 wb.Navigated += new WebBrowserNavigatedEventHandler(wb_Navigated);
 wb.Navigate(_url);
 MessageBox.Show("W00t");
}

protected void wb_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
 WebBrowser wb = (WebBrowser)sender; // Breakpoint
 HtmlDocument hDoc = wb.Document;
}

Это отлично работает;но окно сообщений будет мешать, поскольку это приложение для автоматизации.Когда я удаляю MessageBox.Show(), событие WebBrowser.Navigated никогда не срабатывает.Я попытался заменить эту строку с помощью Thread.Sleep() и приостановить родительский поток.

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

Почему он это делает?Как я могу это исправить?

Если кто-то может предоставить мне способ получить содержимое веб-страницы, заполнить некоторые данные и вернуть содержимое страницы по другую сторону кнопки отправки, и все это на веб-сервере, который не поддерживает команды POST и передачи данных через QueryString, я также приму этот ответ, поскольку все это упражнение будет ненужным.


Решение: В итоге я вообще не использовал BackgroundWorker и подчиненный поток по предложению архитектора команды...Хоть и в ущерб отзывчивости :(

Это было полезно?

Решение

WebBrowser мало что сделает, если он не показан и не связан с потоком пользовательского интерфейса;вы показываете форму, в которой он находится?Вам нужно использовать DOM и т.д.Форма может быть закадровой, если вы не хотите отображать ее пользователю, но в сервисе она не будет работать (например).

Для целей парсинга вы обычно можете имитировать обычный HTML-браузер, используя WebClient и т. д.Разве этого недостаточно?Вы можете использовать такие инструменты, как «Скрипач", чтобы выяснить, какой именно запрос вам нужно отправить на сервер.Более того, вы можете посмотреть Пакет гибкости HTML, который предлагает доступ DOM к HTML без браузера.

Другие советы

События Navigated и DocumentComplete не будут срабатывать, если для видимости WebBrowser установлено значение false.Вы можете обойти это ограничение, сделав веб-браузер видимым, но установив его местоположение так, чтобы он находился за пределами пользовательского интерфейса, например:

wb.Visible = true;
wb.Left = -wb.Width; // notice the minus sign

вам нужно добавить такую ​​строку:

webBrowser1.Navigated += new WebBrowserNavigatedEventHandler(webBrowser1_Navigated);

где webBrowswer1_Navigated — это функция, которую вы хотите вызывать при возникновении события.

Есть ли уже запущенная тема по графическому интерфейсу?Возможно, объект WebBrowser использует поток графического интерфейса для обработки событий.В этом случае вам следует вызвать Application.Run() из потока, создающего WebBrowser (замените на него MessageBox.Show()).Application.Run() будет зависать до тех пор, пока не будет вызван Application.Exit().

Попробую это проверить сейчас.

В итоге я вообще не использовал BackgroundWorker и подчиненный поток по предложению архитектора команды...Хоть и в ущерб отзывчивости :(

Элемент управления WebBrowser не может работать, если он не находится в потоке STA.Если вы хотите использовать экземпляр WebBrowser в потоке, вам нужно создать свой поток и вызвать Thread.SetApartmentState(ApartmentState.STA);

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top