Запуск и управление браузером в другом потоке

У меня есть основной класс графического интерфейса с некоторыми подклассами. Есть +- 3 потока, которые собирают данные из различных интернет-источников и API-шлюзов и т. д.

Теперь из одного из этих потоков я хочу запустить элемент управления веб-браузером, чтобы добавить в свою программу некоторые функции автоматического просмотра. Каждый из подпотоков должен иметь возможность самостоятельно открывать веб-браузер. Поэтому я создал вторую форму окна С#, которая содержит только элемент управления просмотром веб-страниц.

Я уже использую параметр ApartmentState.STA в этом новом потоке для управления веб-браузером. Однако форма2 не отвечает.

Я попытался вызвать Application.Run(); из этой темы, и это делает веб-браузер/form2 отзывчивым. Но тогда мой основной поток перестает работать.

Поэтому я немного не уверен, как действовать дальше. То, что я хочу, вообще возможно?


person Digits    schedule 21.08.2012    source источник
comment
возможный дубликат WebBrowser Control в новом потоке   -  person Hans Passant    schedule 21.08.2012


Ответы (1)


Это должно работать

var th = new Thread(() =>
{
    WebBrowserDocumentCompletedEventHandler completed = null;

    using (WebBrowser wb = new WebBrowser())
    {
        completed = (sndr, e) =>
        {
            //Do Some work

            wb.DocumentCompleted -= completed;
            Application.ExitThread();
        };

        wb.DocumentCompleted += completed;
        wb.Navigate(url);
        Application.Run();
    }
});

th.SetApartmentState(ApartmentState.STA);
th.Start();
th.Join();

при этом я бы использовал WebClient или HttpWebRequest вместе с HtmlAgilityPack для загрузки и анализа HTML-ресурсов.

person L.B    schedule 21.08.2012
comment
Спасибо. Я попробую это. Это не просто загрузка контента, мне также нужно автоматически выбирать определенные кнопки и нажимать их и т. д. Тогда рекомендуется ли использовать WebClient? - person Digits; 21.08.2012
comment
Селен работает очень хорошо. Единственным недостатком является то, что вам нужно запустить компонент сервера Java, и у вас есть раздражающие окна командной строки... Но это работает :) - person Digits; 23.08.2012
comment
Ответ выше также работает, но становится немного громоздким, когда мне нужно перейти на страницу, ввести данные, нажать кнопку, перейти на другую страницу, выполнить поиск данных и т. д. Тогда события dcoumentCompleted вызывают у меня головную боль. - person Digits; 23.08.2012
comment
Ты Бог. Целый день потратил на это. - person Vans S; 12.12.2012
comment
Можно ли также выполнить javascript с этим? - person Henk Jansen; 05.09.2013
comment
Я столкнулся с похожими проблемами и написал оболочку для .NET WebBrowser, чтобы абстрагироваться от проблем цикла сообщений и сделать взаимодействие менее громоздким для более сложных сценариев. Для всех, кто заинтересован в довольно простом безголовом браузере для .NET, я разместил код на GitHub и сделал его доступным через nuget, для получения дополнительной информации см. github.com/LeastOne/WebBrowserWaiter - person LeastOne; 01.11.2014
comment
@L.B, это хороший рабочий способ, но, к сожалению, после 3 навигаций он не освобождает память, до - 15 МБ, после - 50 МБ. IE - 11. Я попробовал GC.Collect и перешел к about:blank, но это не помогло. - person Olexiy Pyvovarov; 13.08.2015
comment
@L.B, что делать, если мне нужно после DocumentCompleted перейти по другой ссылке и использовать другой DocumentCompeteHandler - person Olexiy Pyvovarov; 15.08.2015