Проблема с Application.DoEvents() при ожидании завершения загрузки WebBrowser

Я пытаюсь загрузить содержимое WebBrowser, а после этого хочу добавить текст и прокрутить вниз.

Вот пример моего кода:

webBrowser1.Url = new System.Uri("file:///" + filePath);
webBrowser1.Document.Body.InnerHtml += text;
webBrowser1.Document.Body.ScrollTop = webBrowser1.Document.Body.ScrollRectangle.Height;

Когда я запускаю его, появляется необработанное исключение «Ссылка на объект не указывает на экземпляр объекта». Или, когда я комментирую строку, которая выполняет прокрутку, текст добавляется к предыдущему содержимому веб-браузера, а затем переходит к новому содержимому.

Итак, после 1-й строки моего примера кода я поставил:

while (webBrowser1.ReadyState != WebBrowserReadyState.Complete) Application.DoEvents();

но все портит. Мое приложение делает действительно странные вещи, например, много раз вызывает один и тот же метод, когда его нужно вызвать один раз.

Есть ли решение?


person alcohol is evil    schedule 22.07.2011    source источник
comment
Есть ли у вас какие-либо таймеры или асинхронные методы, работающие в фоновом режиме, которые могут повлиять на это? Есть ли у вас какие-либо события в объекте webBrowser1, которые будут вызываться, скажем, OnReadyStateChanged?   -  person mellamokb    schedule 22.07.2011


Ответы (2)


Я думаю, вы действительно хотите подписаться на DocumentCompleted событие.
Application.DoEvents обрабатывает только ожидающие элементы цикла сообщений Windows.

В любом случае убедитесь, что вы понимаете возможные недостатки вызова DoEvents перед тем, как вообще его использовать.

person Dan Abramov    schedule 22.07.2011
comment
Да, и эта обработка может вызвать проблемы с повторным входом, StackOverflowException (в случае, если DoEvents вызовет метод, который снова вызывает DoEvents) и другие забавные вещи. Лучше убедиться, что вы понимаете, как работает DoEvents, прежде чем вызывать его. - person Ivan Danilov; 22.07.2011
comment
Абсолютно. Я думаю, что путаница с этим методом частично связана с тем, что когда-то популярный Visual Basic 6 имел метод с точно таким же именем, который использовался как плохая замена многопоточности. - person Dan Abramov; 22.07.2011
comment
Ну я не писал на VB6, но он до сих пор используется как замена. С теми же результатами на самом деле :) - person Ivan Danilov; 22.07.2011
comment
Немного оффтоп, но тем не менее. В низкоуровневом нативном программировании в Windows есть аналогичная вещь, называемая «пользовательским APC» или асинхронным вызовом процедуры. Иногда полезно, но и очень опасно. - person Ivan Danilov; 22.07.2011

DoEvents() здесь плохое решение. Вы должны использовать явный поток или BackgroundWorker для загрузки страниц и оставить поток пользовательского интерфейса для обработки других вещей.

person Ivan Danilov    schedule 22.07.2011
comment
WebBrowser не может работать с MTU, а BackgroundWorker создает только потоки MTU. - person Odys; 12.01.2012
comment
@odyodyodys, вы имели в виду MTA — многопоточная квартира? В этом случае использовать этот компонент таким образом — плохая идея. Может быть, это позволяет явно задавать контент (вместо установки Uri) или каким-то образом сделать загрузку контента асинхронной? - person Ivan Danilov; 12.01.2012