Метод WPF для ожидания события DocumentCompleted - PullRequest
0 голосов
/ 06 сентября 2011

Я знаю, что об этом спрашивали раньше , но я не думаю, эти решения являются гибкими.Событие DocumentCompleted должно использоваться для определения времени завершения загрузки, а не как метод выполнения работы.Если вам нужно выполнить несколько различных задач, по которым приходится выполнять навигацию по нескольку раз, размещение логики в событии DocumentCompleted превращает ее в грязный коммутатор / маршрутизатор, который трудно читать и обслуживать.

Вам нужночто-то, что может действительно ждать во время выполнения вашего метода, выполняя навигацию, чтобы вы могли продолжить свою задачу в методе, в котором вы уже находитесь. Мой первый метод - это фактический метод Wait ().

Я думаю, что-то вроде этого близко:

void WaitForLoad()
    {
        isLoading = true;
        while (isLoading)
        {
            if (Application.Current == null) break;
            Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, (DispatcherOperationCallback)delegate(object unused) { return null; }, null);
        }
    }

И установить Isloading в false в событии DocumentCompleted.

Вы сможете просто вызывать этот метод после любого действия, которое вызовет загрузку страницы.Это работает, у него есть некоторые проблемы.

1) отправляет загрузку ЦП для приложения до 35% до загрузки страницы, даже если ничего не происходит.

2) если приложение пытается закрыться во время работы, цикл продолжит работу и оставит приложение открытым без окон, следовательно, потребуется перерыв, когда приложение будет нулевым.

Можно ли это исправить, или я ошибаюсь?

Редактировать : Я попытался реализовать решение ManualResetEvent ниже, но это привело к ряду других проблем, в которых я не уверенможет быть решена без создания более сложной ситуации, чем описанная выше.Поскольку WebBrowser находится на пользовательском интерфейсе, блокировка потока останавливает все приложение.Если работа выполняется в фоновом потоке, ее можно заблокировать, но доступ к веб-браузеру становится очень трудным.

Ответы [ 2 ]

2 голосов
/ 06 сентября 2011

В вашей ситуации звучит так, будто вы хотите, чтобы определенный поток блокировался во время ожидания загрузки документа. В этом случае вы бы сделали что-то вроде этого:

  protected ManualResetEvent _resetEvent = new ManualResetEvent(false);

  public void WaitingThread()
  {
      _resetEvent.WaitOne();

      // Do stuff after the web browser completes. 
  }

  public void LoadWebPage()
  {
      webBrowser.Navigate(new Uri(url));
      webBrowser.DocumentCompleted = (s, e) => { _resetEvent.Set(); };
  }

Как правило, когда документ завершается, вы сигнализируете о событии и всех потоках, ожидающих события, которые разблокируются и продолжают выполняться.

0 голосов
/ 06 сентября 2011

Я заметил, что вы используете Dispatcher.CurrentDispatcher.Invoke, это хорошо для вызова вашего метода, который каким-то образом обновляет пользовательский интерфейс из другого потока.Но из предоставленного кода я не вижу кода в другом потоке, кроме пользовательского интерфейса.Так что

  1. Запустите этот код в другом потоке.

  2. На событии закрытия вашего приложения вы можете сделать isLoading=false; И даже больше, если вызванный метод является чем-то вроде длительного запуска, вставьте

    if (! IsLoading)вернуть;

    // или в другом приложении подходящим способом прервать выполнение

РЕДАКТИРОВАТЬ:

Еще лучший способ справиться с этимв многопоточности, а затем просто передать логическую переменную, используется некоторый объект синхронизации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...