Элемент управления WebBrowser: «Указанное преобразование недопустимо». - PullRequest
2 голосов
/ 01 мая 2011

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

//in constructor of main form
Thread.CurrentThread.ApartmentState = ApartmentState.STA;
this.CheckForIllegalCrossThreadCalls = false;

mainThreadHandle = new Thread(mainThread);
mainThreadHandle.Start();

private void mainThread()
{
    wbMain.Navigate("http://example.com/");

    //navigating is set to false in the document complete event.
    navigating = true;

    while (navigating == true)
        Thread.Sleep(5000);

    try
    {
        //Where I get the issues
        MessageBox.Show(wbMain.DocumentText);
    }
    catch (Exception e)
    {

    }

    Thread.Sleep(1000);
}

Ответы [ 2 ]

8 голосов
/ 01 мая 2011

WebBrowser является COM компонентом под капотом. Квартира с многопоточностью, COM заботится о вызове своих методов безопасным для потоков способом. По этой причине ваш вызов Navigate () работает, он фактически выполняется в потоке пользовательского интерфейса. Что не работает, так это свойство DocumentText, оно реализовано в оболочке .NET, и они в некоторой степени искали код. Он взрывается, когда поддержка взаимодействия COM в CLR замечает, что поток в MTA пытается получить доступ к свойству компонента, который живет на STA.

Ваш вызов SetApartmentState () неверен. Это сделано не с того потока, поток пользовательского интерфейса уже является STA. Кроме того, причина того, что это не бомба, вы не можете изменить состояние квартиры потока после его запуска. Вы должны вызвать его в объекте Thread, который вы создали. Это по-прежнему не решает вашу проблему, два потока STA не совместимы.

Два основных способа решения вашей проблемы. Во-первых, вы сами создаете объект WebBrowser в отдельном потоке STA. Код в этом ответе показывает, как это сделать.

Браузер, который вы создаете таким образом, также не отображается в вашей форме. Что является вторым способом, соберите вызов сами с помощью Control.Invoke (). Однако делать это довольно бессмысленно, так как весь ваш код выполняется в потоке пользовательского интерфейса, вы не получаете параллелизма. Здесь нет бесплатного обеда. Запуск его в потоке только дает вам головную боль. Если вам нужно время для обработки текста документа, запустите этот код в отдельном потоке.

1 голос
/ 01 мая 2011

Почему бы не использовать модель событий при работе с управлением WebBrowser?

Навигация , Навигация , ProgressChanged , DocumentCompleted

...