【发布时间】:2016-03-31 20:42:29
【问题描述】:
我正在尝试创建一种方法,使用 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");
}
}
当有人在TextBox(我用google.com测试过)中输入一个URL并点击Button时的结果是:
- 导航已触发
- DocumentCompleted 已触发
- ... ... 什么都没有
如果然后在WebBrowser 上单击一个链接,例如顶部的图片,则会发生以下情况:
- 导航已触发
- DocumentCompleted 已触发
- 1 秒后 ... 完成加载
如果我再次点击Button 会发生什么:
- 导航已触发
- DocumentCompleted 已触发
- 1 秒后 ... 完成加载
- 显然,如果我之前没有点击页面中的任何链接,那么我会得到第二个 DoneLoading
MessageBox。
所以,我的问题很简单:第一次出现什么问题,我该如何解决?
编辑:我刚刚对一个不同的网站进行了测试,其中事件多次触发,并且在这些网站上运行良好。所以它实际上是网站,它只触发一次,而且它似乎只是第一次出现的问题。
【问题讨论】:
标签: c# .net system.reactive