我不是新编程,但我很擅长在C#WinForm应用程序中使用WebBrowser控件。
我有两个动态加载到表单上的WebBrowser控件。第一个导航到URL,完成后我将它的DocumentText加载到HtmlAgilityPack文档中。我使用XPath来解析一些链接,然后传递给第二个浏览器控件。一切正常,直到第二个浏览器控件加载后。它的.DocumentText长度不到700个字节。如果我绕过剩下的例程并返回到屏幕,则在第二个控件中显示正确的完整页面,但是我无法在例程中进行此操作。代码的基本内容如下。
private WebBrowser webBrowser = new WebBrowser();
private WebBrowser webBrowser2 = new WebBrowser();
private TaskCompletionSource<bool> tcs = null;
private TaskCompletionSource<bool> tcs2 = null;
private string lastnav = "";
private string lastMessage = "";
private void webBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
lastnav = e.Url.ToString();
this.txtNavigated.Text += e.Url.ToString() + "\r\n\r\n";
if (webBrowser.Document != null && webBrowser.Document.Cookie != null)
this.txtNavigated.Text += webBrowser.Document.Cookie + "\r\n\r\n";
this.txtNavigated.Update();
}
private async void TryNavigate(string url)
webBrowser.Location = new System.Drawing.Point(12, 226);
webBrowser.Size = new System.Drawing.Size(1070,100);
webBrowser2.Location = new System.Drawing.Point(12, 327);
webBrowser2.Size = new System.Drawing.Size(1070, 100);
this.Controls.Add(webBrowser);
this.Controls.Add(webBrowser2);
tcs = new TaskCompletionSource<bool>();
WebBrowserDocumentCompletedEventHandler documentCompletedHandler = (sender2, e2) => tcs.TrySetResult(true);
WebBrowserNavigatingEventHandler docNavigatingHandler = webBrowser_Navigating;
try
{
Uri baseUri = new Uri("https://www.labcorp.com/wps/portal/provider/testmenu");
Uri newUri = null;
webBrowser.DocumentCompleted += documentCompletedHandler;
webBrowser.Navigating += docNavigatingHandler;
try
{
webBrowser.Navigate(baseUri.AbsoluteUri);
await tcs.Task;
}
catch (WebException webex) {
lastMessage = webex.Message;
}
catch (Exception ex)
{
lastMessage = ex.Message;
}
finally
{
webBrowser.DocumentCompleted -= documentCompletedHandler;
}
webBrowser2.Navigate("localhost");
webBrowser2.Document.Cookie = webBrowser.Document.Cookie;
webBrowser2.Navigating += docNavigatingHandler;
webBrowser2.DocumentCompleted += documentCompletedHandler2;
HtmlAgilityPack.HtmlDocument azlinks = new HtmlAgilityPack.HtmlDocument();
azlinks.LoadHtml(webBrowser.DocumentText);
// get A - Z
var azlinkNodes = azlinks.DocumentNode.SelectNodes("//div[@class='searchDiv']/table/tr/td/a");
if (azlinkNodes != null)
{
tcs2 = new TaskCompletionSource<bool>();
WebBrowserDocumentCompletedEventHandler documentCompletedHandler2 = (sender2, e2) => tcs2.TrySetResult(true);
if (Uri.TryCreate(baseUri, azlinkNodes[0].Attributes["href"].Value, out newUri))
{
try
{
webBrowser2.Navigate(newUri);
await tcs2.Task;
}
finally
{
webBrowser2.DocumentCompleted -= documentCompletedHandler2;
}
// **************************************************
// will not come out of this test loop
//while (webBrowser2.DocumentText.Length < 10000) {
// webBrowser2.Update();
// System.Threading.Thread.Sleep(500);
//}
MessageBox.Show("webBrowser2.DocumentText.Length = " + webBrowser2.DocumentText.Length.ToString(), "Length");
}
}
}
catch (Exception ex)
{
lastMessage = ex.Message;
}
}
我在表单上创建了一个测试按钮,以便在例程返回到屏幕后,我可以单击它并检查第二个浏览器的内容。
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("webBrowser2.DocumentText.Length = " + webBrowser2.DocumentText.Length.ToString(), "Length");
}
点击按钮后,第二个浏览器的.DocumentText长度是正确的(大约130K +),但我没有看到让它在例程中间返回的方法。正如你在注释掉的代码中看到的那样,我做了一个测试,看看Update()是否会有所帮助,但它会永远停留在循环中。
有没有人知道如何在不返回屏幕的情况下完成加载?
任何帮助肯定会受到赞赏。
由于
答案 0 :(得分:0)
我的猜测是,在for
循环的第二次迭代中,tcs2.Task
已经处于已完成状态,因此await立即返回,您继续处理尚未加载的文档。解决此问题的最简单方法是在tcs2
循环内创建documentCompletedHandler2
以及for
。
答案 1 :(得分:0)
你不能使用Thread.Sleep,你需要继续抽取消息。使用DoEvents很诱人,但这也是错误的。检查一下这些新想法。 - Noseratio 11小时前
然后尝试用等待Task.Delay(TimeSpan.FromMilliseconds(500))替换Thread.Sleep调用,以便主线程可以自由地做任何webbrowser2需要它 - vadim 9小时前
这确实有效。我不知道他们的AJAX服务器昨晚是否很慢或问题是什么,但我今天再次重新审视了所有这些建议,这个建议在大约1.5秒之后就可以运行了。谢谢你的帮助!
我会将其标记为答案,但并未将其作为一个发布。