我正在尝试创建一个程序,通过我们的缺陷跟踪系统的Web界面一次克隆多个错误。在继续之前,如何在页面完全加载之前等待?
//This is pseudo code, but this should give you an idea of what I'm trying to do. The
//actual code uses multi-threading and all that good stuff :).
foreach (string bug in bugs)
{
webBrowser.Navigate(new Uri(url));
webBrowser.Document.GetElementById("product").SetAttribute("value", product);
webBrowser.Document.GetElementById("version").SetAttribute("value", version);
webBrowser.Document.GetElementById("commit").InvokeMember("click");
//Need code to wait for page to load before continuing.
}
答案 0 :(得分:31)
这段代码对我很有帮助。也许它也适合你
wb.Navigate(url);
while(wb.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
MessageBox.Show("Loaded");
答案 1 :(得分:25)
尝试使用DocumentCompleted Event
webBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);
void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
webBrowser.Document.GetElementById("product").SetAttribute("value", product);
webBrowser.Document.GetElementById("version").SetAttribute("value", version);
webBrowser.Document.GetElementById("commit").InvokeMember("click");
}
答案 2 :(得分:18)
在不阻止UI线程的情况下执行此操作的最佳方法是使用.net 4.5中引入的Async和Await 您可以将其粘贴到代码中,只需将浏览器更改为您的web浏览器名称即可。 这样,您的线程等待要加载的页面,如果它没有准时,它会停止等待并且您的代码继续运行:
private async Task PageLoad(int TimeOut)
{
TaskCompletionSource<bool> PageLoaded = null;
PageLoaded = new TaskCompletionSource<bool>();
int TimeElapsed = 0;
Browser.DocumentCompleted += (s, e) =>
{
if (Browser.ReadyState != WebBrowserReadyState.Complete) return;
if (PageLoaded.Task.IsCompleted) return; PageLoaded.SetResult(true);
};
//
while (PageLoaded.Task.Status != TaskStatus.RanToCompletion)
{
await Task.Delay(10);//interval of 10 ms worked good for me
TimeElapsed++;
if (TimeElapsed >= TimeOut * 100) PageLoaded.TrySetResult(true);
}
}
您可以像这样使用它,在异步方法中,或在按钮单击事件中,只需将其设为异步:
private async void Button1_Click(object sender, EventArgs e)
{
Browser.Navigate("www.example.com");
await PageLoad(10);//await for page to load, timeout 10 seconds.
//your code will run after the page loaded or timeout.
}
答案 3 :(得分:12)
受到2005年12月开始的Watir WatiN开发的启发,可以为.Net语言进行类似的Web应用程序测试。从那时起,WatiN已经发展成为一个易于使用,功能丰富且稳定的框架。 WatiN是用C#开发的,旨在为您提供一种使用.Net的Internet Explorer和FireFox自动化测试的简便方法......
答案 4 :(得分:8)
任务方法对我有用,但Browser.Task.IsCompleted必须更改为PageLoaded.Task.IsCompleted。
抱歉,我没有添加评论,这是因为我需要更高的声誉才能添加评论。
答案 5 :(得分:3)
yuna和bnl代码在以下情况下失败;
示例失败:
第一个等待完成。但是,第二个用invokemember(&#34;提交&#34;)没有。调用工作。但ReadyState.Complete在其真正完成之前就像其已完成一样:
wb.Navigate(url);
while(wb.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
MessageBox.Show("ok this waits Complete");
//navigates to new page
wb.Document.GetElementById("formId").InvokeMember("submit");
while(wb.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
MessageBox.Show("webBrowser havent navigated yet. it gave me previous page's html.");
var html = wb.Document.GetElementsByTagName("HTML")[0].OuterHtml;
如何解决这种不必要的情况:
用法
public myForm1 {
myForm1_load() { }
// func to make browser wait is inside the Extended class More tidy.
WebBrowserEX wbEX = new WebBrowserEX();
button1_click(){
wbEX.Navigate("site1.com");
wbEX.waitWebBrowserToComplete(wb);
wbEX.Document.GetElementById("input1").SetAttribute("Value", "hello");
//submit does navigation
wbEX.Document.GetElementById("formid").InvokeMember("submit");
wbEX.waitWebBrowserToComplete(wb);
// this actually waits for document Compelete. worked for me.
var processedHtml = wbEX.Document.GetElementsByTagName("HTML")[0].OuterHtml;
var rawHtml = wbEX.DocumentText;
}
}
//put this extended class in your code.
//(ie right below form class, or seperate cs file doesnt matter)
public class WebBrowserEX : WebBrowser
{
//ctor
WebBrowserEX()
{
//wired aumatically here. we dont need to worry our sweet brain.
this.DocumentCompleted += (o, e) => { webbrowserDocumentCompleted = true;};
}
//instead of checking readState, get state from DocumentCompleted Event
// via bool value
bool webbrowserDocumentCompleted = false;
public void waitWebBrowserToComplete()
{
while (!webbrowserDocumentCompleted )
{ Application.DoEvents(); }
webbrowserDocumentCompleted = false;
}
}
答案 6 :(得分:2)
选择Selenium(http://seleniumhq.org)或WatiN(http://watin.sourceforge.net)以节省一些工作。
答案 7 :(得分:1)
如果您使用的是InternetExplorer.Application COM对象,请检查ReadyState属性的值为4.
答案 8 :(得分:1)
我认为WebBrowser控件的DocumentCompleted事件可以让你到达目的地。
答案 9 :(得分:1)
假设“commit”元素表示标准的表单提交按钮,那么您可以将事件处理程序附加到WebBrowsers Navigated事件。
答案 10 :(得分:1)
while (true)
{//ie is the WebBrowser object
if (ie.ReadyState == tagREADYSTATE.READYSTATE_COMPLETE)
{
break;
}
Thread.Sleep(500);
}
我用这种方式等待页面加载。