2009-02-24 189 views
17

我試圖創建一個程序,通過我們的缺陷跟蹤系統的Web界面一次克隆多個錯誤。在我繼續之前,如何在頁面完全加載之前等待?C#如何在繼續之前等待網頁完成加載

//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

我有同樣的問題,但WebView。任何想法如何等待,直到它完成加載? – yalematta 2016-08-11 11:26:59

回答

18

嘗試DocumentCompleted事件

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"); 
} 
+1

這段代碼是否意味着Web瀏覽器在執行下面的命令之前總是會等待完成? – AdorableVB 2017-04-26 00:16:54

+0

我的頁面裸露的骨骼結構加載非常快,但我有JS代碼,它將數據庫中的內容加載到不同的DIV中,並且需要幾秒鐘的時間。是否還有其他事件可以觸發? – 2017-08-02 21:13:45

0

如果您使用的是InternetExplorer.Application COM對象,檢查ReadyState屬性爲4

11

退房的價值WatiN project:由Watir發展華廷的靈感

開始在2005年12月,爲.Net語言進行類似的Web應用程序測試。自那時起,WatiN已經發展成爲一個易於使用,功能豐富和穩定的框架。華廷在C#開發的,旨在爲您帶來一種簡單的方法使用的.Net自動與Internet Explorer和Firefox你的測試...

+1

不能同意更多。我已經走過了兩條路 - 滾動您自己的WebBrowser控制噩夢和WatiN。 WebBrowser可以同步,但如果你讓WatiN爲你完成工作,你會在以後感謝你。 – 2009-02-24 22:52:49

0

假設「提交」元素代表一個標準的形式提交按鈕,那麼你可以將一個事件處理程序化網頁瀏覽器導航中的事件。

28

此代碼對我非常有幫助。也許這可能是你也做到這一點,而不會阻塞UI線程

wb.Navigate(url); 
while(wb.ReadyState != WebBrowserReadyState.Complete) 
{ 
    Application.DoEvents(); 
} 
MessageBox.Show("Loaded"); 
+2

作品。但是CPU負載會在此上升「,而」 – Alex 2012-04-19 22:53:33

15

最好的辦法是使用異步和.NET 4.5等待出臺。
您可以將其粘貼到您的代碼中,只需將瀏覽器更改爲您的瀏覽器名稱即可。 這樣一來,你的線程等待網頁加載,如果它不上的時候,它停止等待,你的代碼會繼續運行:

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. 
} 
6

工作方法爲我工作,除了Browser.Task.IsCompleted已改爲PageLoaded.Task.IsCompleted。

對不起,我沒有添加評論,這是因爲我需要更高的聲譽來添加評論。

-1

看了上面的一些答案之後,我發現了一個常見的缺陷。您無法普遍使用上述任何解決方案。這是最好的方式去:

private void let_Load(string url) 
    { 
     // Waits for page to load 
     // If page doesn't load in 10 seconds, the while loop is exited with error 
     Stopwatch s = new Stopwatch(); 
     s.Start(); 
     while (url != webbrowser1.Url.ToString()) 
     { 
      Application.DoEvents(); 
      if (url == webbrowser1.Url.ToString()) 
       break; 
      if (s.Elapsed > TimeSpan.FromSeconds(9.9)) 
       { 
       richTextBox.Text = "Error: Page is unable to Load."; 
       break; 
       } 
     } 
    } 

現在,所有你需要做的就是調用該函數並傳遞需要加載的網址!此外,由於秒錶,如果您的網頁從未加載或存在某種輸入錯誤,您的代碼不會中斷。該代碼將在10秒後自動停止循環。

// Short Example 
webbrowser1.Navigate("http://twitter.com"); 
let_load("http://twitter.com"); 

快速注意:確保網頁瀏覽器已經有一個網址。只需在屬性中設置url,以便在運行應用程序時加載它。

2

idk爲什麼但yuna和bnl代碼在下面的情況下失敗;

第一個等待completed.but,第二個與invokemember(「提交」)沒有。調用作品。但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; 

如何解決這種不需要的情況;

button1_click(){ 
     wb.Navigate("site1.com"); 
     waitWebBrowserToComplete(wb); 

     wb.Document.GetElementById("input1").SetAttribute("Value", "hello"); 
     //submit does navigation 
     wb.Document.GetElementById("formid").InvokeMember("submit"); 
     waitWebBrowserToComplete(wb); 
     // this actually waits for document Compelete. worked for me. 

     var processedHtml = wb.Document.GetElementsByTagName("HTML")[0].OuterHtml; 
     var rawHtml = wb.DocumentText; 
} 


//instead of checking readState . we get state from DocumentCompleted Event via bool value 
bool webbrowserDocumentCompleted = false; 
public static void waitWebBrowserToComplete(WebBrowser wb) 
{ 
    while (!webbrowserDocumentCompleted) 
    { 
     Application.DoEvents(); 
    } 
    webbrowserDocumentCompleted = false; 
    } 

    form_load(){ 
    wb.DocumentCompleted += (o, e) => { 
     webbrowserDocumentCompleted = true; 
     }; 
    } 
0
while (true) 
     {//ie is the WebBrowser object 
      if (ie.ReadyState == tagREADYSTATE.READYSTATE_COMPLETE) 
      { 
       break; 
      } 
      Thread.Sleep(500); 
     } 

我用這樣的方式來等待,直到頁面加載。

相關問題