C # IE BHO: Работают ли асинхронно, сохраняя при этом тот же поток? - PullRequest
2 голосов
/ 23 апреля 2009

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

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

Моя первая попытка состояла в том, чтобы фоновая коммуникация с сервером делала свое дело на основе событий: моя программа инициировала обмен данными из события mshtml (например, BeforeNaviagate2 или 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), но я обнаружил, что ожидание доступности тега , если связь с моим сервером завершится, прежде чем загруженная страница пользователя также заблокирует IE - бросить его в бесконечный цикл, пока мой код ожидает тело HTML, в то время как страница не имеет возможности обновлять себя до вышеуказанного цикла.

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

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

Спасибо!

-Tom

1 Ответ

1 голос
/ 23 апреля 2009

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

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

...