С# IE БХО:Работаете ли асинхронно, сохраняя при этом один и тот же поток?

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

Вопрос

У меня есть IE BHO, который находится в разработке на C#.Предполагается, что пользователь дождется, пока пользователь выполнит какие-то действия, свяжется с нашим сервером и загрузит некоторые данные, а затем изменит DOM загруженной в данный момент веб-страницы с результатами.

Я сталкиваюсь с некоторыми, казалось бы, непреодолимыми проблемами, связанными с правилами разделения и потоков COM, а именно, я не могу получить доступ к IE DOMDocument за пределами текущего потока и не могу придумать никакого способа запустить что-то асинхронно без блокировки. вверх IE, пока он не будет завершен.

Моя первая попытка заключалась в том, что фоновая связь с сервером выполнялась на основе событий:моя программа инициировала бы связь из события mshtml (например, BeforeNavigate2 или DocumentComplete) и отправляла бы результаты из отдельного обработчика событий, запускаемого коммуникационным объектом сервера, когда он завершил свою работу.

Этот метод отлично работал в быстром симуляторе, который я собрал (простое приложение с элементом управления WebBrowser), но в IE он вызывал исключение COM, потому что я пытался изменить DOM страницы через отдельный поток.

Поэтому я попытался сохранить все в одной функции и заставить мой код ждать, пока объект связи с сервером выполнит свою работу с помощью цикла while, например:


    int waited = 0;
    while (!OurServerCommRequest.ready) {
        System.Threading.Thread.Sleep(1);
        Application.DoEvents();
        waited++;

        if (waited > constants.TIMEOUT_OURSERVER_REQUEST) {
            log.wL("Timed out");
        }

    }

Проблема с этим подходом заключается в том, что, хотя код остается в исходном потоке, он выполняется синхронно с процессом IE, в котором он запущен (в IE8 это один процесс на вкладку - как в Google Chrome - кажется)...поэтому блокирую интерфейс IE до тех пор, пока не завершится связь с моим сервером.

Первоначально я хотел начать обработку, как только URL-адрес станет доступен (через событие NavigationComplete2), но я обнаружил, что ожидание доступности тега <body>, если связь с сервером завершится до загрузки страницы пользователя, также приведет к блокировке IE - бросок его в бесконечный цикл, пока мой код ожидает тела HTML, в то время как страница не может обновляться в вышеупомянутом цикле.

Я думал о том, чтобы переместить все это в javascript реальной страницы пользователя, но кажется, что, делая это, я открываю банку червей в спорах с проблемами безопасности XSS.

Так...мой вопрос такой:Можно ли асинхронно запускать код в C# IE BHO, сохраняя при этом возможность манипулировать DOM страницы пользователя?Я расспросил некоторых друзей, и большинство людей сказали мне, что это маловероятно.Я все еще новичок в COM и C#, пришедший из C/VB.net/JS/AS.

Спасибо!

-Том

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

Решение

Вам необходимо маршалировать объект DOM из потока, в котором он был создан, в ваш рабочий поток. Здесь представляет собой очень подробное описание того, как COM и C# взаимодействуют друг с другом.

Все объекты IE DOM являются объектами STA.

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