2013-02-12 54 views
6

異步方法我使用.NET 4.0和我一直試圖弄清楚如何使用異步方法來等待DocumentCompleted事件完成並返回值。我的原始代碼在上面,我怎麼能把它變成這種情況下的異步/等待模型?與完成的事件

private class BrowserWindow 
    { 
     private bool webBrowserReady = false; 
     public string content = ""; 


     public void Navigate(string url) 
     { 

      xxx browser = new xxx(); 

      browser.DocumentCompleted += new EventHandler(wb_DocumentCompleted); 
      webBrowserReady = false; 
      browser.CreateControl(); 
      if (browser.IsHandleCreated) 
       browser.Navigate(url); 


      while (!webBrowserReady) 
      { 
       //Application.DoEvents(); >> replace it with async/await 
      } 

     } 

     private void wb_DocumentCompleted(object sender, EventArgs e) 
     { 
      try 
      { 
       ... 

        webBrowserReady = true; 

        content = browser.Document.Body.InnerHtml; 

      } 
      catch 
      { 

      } 

     } 

     public delegate string AsyncMethodCaller(string url); 
    } 

回答

9

所以我們需要一個方法,當DocumentCompleted事件觸發時返回一個任務。任何時候你需要對於給定的情況下,您可以創建這樣的方法:一旦你有,你可以使用

public static Task WhenDocumentCompleted(this WebBrowser browser) 
{ 
    var tcs = new TaskCompletionSource<bool>(); 
    browser.DocumentCompleted += (s, args) => tcs.SetResult(true); 
    return tcs.Task; 
} 

await browser.WhenDocumentCompleted(); 
+0

感謝您的很好的解決方案,但一個問題是,我」 m使用vs 2010和.net 4.0,所以我必須使用舊式而不是等待synctax(4.5)。我有點困惑如何讓它在4.0 – 2013-02-12 16:42:03

+1

@namvo工作你明確地說,你想要一個使用async/await的解決方案,所以我認爲你使用的是兼容包。如果你不是,那麼只需在方法返回的任務上使用'ContinueWith'('WhenDocumentCompleted'事件將在4.0中工作),並將文檔完成後運行的代碼放在那裏。爲了方便起見,您最可能要使用lambda表達式。 – Servy 2013-02-12 16:46:28

+0

謝謝,我會玩它。 – 2013-02-12 16:54:00