Я пытаюсь создать метод, используя элемент управления WebBrowser
, перейти на веб-страницу и выполнить кастинг, пока страница не будет полностью загружена.Реактивные расширения, ожидающие события, не работают в первый раз около
К сожалению, зная, полностью ли загружена страница или нет, это не так просто и просто основано на событиях Navigating
и DocumentCompleted
.
Вместе они делают пару: когда Navigating
пожаров, DocumentCompleted
всегда будет стрелять после этого.
DocumentCompleted
К сожалению, пожары для каждого кадра, который загружен, поэтому он может стрелять несколько раз на одной странице, а это означает, что это не редкость, чтобы увидеть следующую последовательность: Navigating
- DocumentCompleted
- Navigating
- DocumentCompleted
.
В результате я определил «полностью загруженную страницу» следующим образом: если DocumentCompleted
уволил, а секунда истекла, а Navigating
снова выстрелил в течение этого времени.
Во всяком случае, у меня есть следующий как мой код Rx, чтобы попытаться сделать выше:
_pageLoaded = navigating.Select(_ => documentCompleted.Delay(TimeSpan.FromSeconds(1))).Switch().FirstAsync();
Потом где-то я делаю await _pageLoaded
, прежде чем продолжить.
Однако, по какой-то странной причине, это не работает в первый раз. Поэтому, когда приложение загружается, а WebBrowser
перемещается где-то, он застревает на await _pageLoaded
, пока оба Navigating
и DocumentCompleted
не зажгут огонь (т. Е. Я перейду к другому URL-адресу или тому же).
Я быстро проект просто проверить это и события Navigating
и DocumentCompleted
огонь, как и ожидалось, вот мой полный код:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private IObservable<object> _pageLoaded;
private void Form1_Load(object sender, EventArgs e)
{
var navigating = Observable.FromEventPattern(webBrowser, "Navigating");
var documentCompleted = Observable.FromEventPattern(webBrowser, "DocumentCompleted");
_pageLoaded = navigating.Select(_ => documentCompleted.Delay(TimeSpan.FromSeconds(1))).Switch().FirstAsync();
}
private async void button1_Click(object sender, EventArgs e)
{
webBrowser.Navigate(textBox1.Text);
await _pageLoaded;
MessageBox.Show("DoneLoading");
}
private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
MessageBox.Show("DocumentCompleted fired");
}
private void webBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
MessageBox.Show("Navigating fired");
}
}
В результате, когда кто-то вводит URL в TextBox
(я тестировал с google.com) и попадает в Button
является:
- Навигационное выстрелил
- DocumentCompleted выстрелил
- ... ... ничего
Если затем на WebBrowser
я нажимаю на ссылку, говорят изображения в верхней части, например, происходит следующее:
- Навигационное выстрелил
- DocumentCompleted выстрелил
- 1 сек позже ... DoneLoading
Если я снова попал в Button
что тогда случается:
- Навигационное выстрелил
- DocumentCompleted выстрелил
- 1 сек позже ...DoneLoading
- И, очевидно, если я еще не нажал ни одной ссылки на предыдущей странице, я получу вторую DoneLoading
MessageBox
.
Итак, мой вопрос прост: что это не работает в первый раз и как его исправить?
EDIT: Я просто сделал тест с другим сайтом, где события срабатывают многократно, и он отлично работает на этих сайтах. Таким образом, это буквально веб-сайты, где он срабатывает только один раз, и, похоже, это проблема только в первый раз.
Это была проблема. Это происходит из мышления Observables как событий и мышления, что «navigating = Observable.FromEventPattern (webBrowser,« Навигация »);« подписал меня на любое генерируемое им событие, что он просто поместит их в «поток», ожидающий все, что я хотел, когда захочу. Теперь я знаю лучше;) Спасибо! – JohnUbuntu
Вы также можете найти этот ответ полезным: http://stackoverflow.com/questions/19895373/how-to-use-observable-fromevent-instead-of-fromeventpattern-and-avoid-string-lit/19896246#19896246 –