2013-08-25 27 views
3

下面的代碼。WebBrowser瀏覽功能不起作用,並且不會調用處理程序

我想導航到一個網站,並閱讀信息,問題是Navigate不起作用,唯一被調用的事件是導航,並且打印的Url爲空,其他事件永遠不會被調用。 我錯過了什麼?我必須使用Form類才能導航?我不能以編程方式從控制檯應用程序使用它嗎?

請幫忙。

class WebNavigator 
{ 
    private readonly WebBrowser webBrowser; 

    public WebNavigator() 
    { 
     webBrowser = new WebBrowser 
     { 
      AllowNavigation = true 
     }; 

     webBrowser.Navigated += webBrowser_Navigated; 
     webBrowser.Navigating += webBrowser_Navigating; 
     webBrowser.DocumentCompleted += webBrowser_DocumentCompleted; 
    } 

    // Navigates to the given URL if it is valid. 
    public void Navigate(string address) 
    { 
     if (String.IsNullOrEmpty(address)) return; 
     if (address.Equals("about:blank")) return; 
     if (!address.StartsWith("http://") && 
      !address.StartsWith("https://")) 
     { 
      address = "http://" + address; 
     } 
     try 
     { 
      Trace.TraceInformation("Navigate to {0}", address); 
      webBrowser.Navigate(new Uri(address)); 
     } 
     catch (System.UriFormatException) 
     { 
      Trace.TraceError("Error"); 
      return; 
     } 
    } 

    // Occurs when the WebBrowser control has navigated to a new document and has begun loading it. 
    private void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e) 
    { 
     Trace.TraceInformation("Navigated to {0}", webBrowser.Url); 
    } 

    // Occurs before the WebBrowser control navigates to a new document. 
    private void webBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e) 
    { 
     Trace.TraceInformation("Navigating to {0}", webBrowser.Url); 
    } 

    private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
    { 
     var wb = sender as WebBrowser; 
     Trace.TraceInformation("DocumentCompleted {0}", wb.Url); 
    } 
} 

回答

6

我會利用await/async

用法:

static async void DoWork() 
{ 
    var html = await GetHtmlAsync("http://www.google.com/"); 
} 

的實用方法

static Task<string> GetHtmlAsync(string url) 
{ 
    var tcs = new TaskCompletionSource<string>(); 

    var thread = new Thread(() => 
    { 
     WebBrowser wb = new WebBrowser(); 

     WebBrowserDocumentCompletedEventHandler documentCompleted = null; 
     documentCompleted = async (o, s) => 
     { 
      wb.DocumentCompleted -= documentCompleted; 
      await Task.Delay(2000); //Run JS a few seconds more 

      tcs.TrySetResult(wb.DocumentText); 
      wb.Dispose(); 
      Application.ExitThread(); 
     }; 

     wb.ScriptErrorsSuppressed = true; 
     wb.DocumentCompleted += documentCompleted; 
     wb.Navigate(url); 
     Application.Run(); 
    }); 

    thread.SetApartmentState(ApartmentState.STA); 
    thread.Start(); 

    return tcs.Task; 
} 
1

你提到這是一個控制檯應用程序。要使WebBrowser在控制檯應用程序中工作,您需要確保瀏覽器的線程是一個STA線程(thread.SetApartmentState(ApartmentState.STA)。此外,爲了能夠處理事件,線程必須抽取消息(Application.Run)。考慮到這一點,您可能希望創建一個單獨的線程(從主控制檯線程)來運行WebBrowser。

1

感謝您的回答。 該問題已通過添加此while子句來解決,其中包括Application.DoEvents();

  webBrowser.Navigate(new Uri(address)); 
      while (!navigationCompleted) 
      { 
       Application.DoEvents(); 
       Thread.Sleep(navigationPollInterval); 
      } 

我不知道這是否是最好的解決方案,我將不勝感激聽到更好的解決方案。

+2

什麼是變量'navigationCompleted'變量後面的代碼?沒有這個,這段代碼將無法工作。 –