暂停程序流直到 WebBrowser 加载页面

Pause program flow until WebBrowser loads a page

我必须使用 WebBrowser 控件在 WPF 应用程序 (.NET v4.0) 中连续加载几个页面,最简单的暂停方法是使用 while 循环并检查 IsLoaded 属性。我想知道是否有更好的东西。以下 SO 响应建议使用 AutoResetEvent 但它似乎不起作用,即未触发 LoadCompleted 事件并且从未设置 AutoResetEvent。有什么我错过的吗

private Uri firstURI = new Uri("http://google.com", UriKind.RelativeOrAbsolute);
private Uri secondURI = new Uri("http://duckduckgo.com/", UriKind.RelativeOrAbsolute);
AutoResetEvent logEvent = new AutoResetEvent(false);

public MainWindow() 
{    
  InitializeComponent();
  webBrowser.Loaded += webBrowser_Loaded;
  webBrowser.LoadCompleted += webBrowser_LoadCompleted;
  webBrowser.Navigate(firstURI);
  while(webBrowser.IsLoaded()){}; //logEvent.WaitOne();
  webBrowser.Navigate(secondURI);
  while(webBrowser.IsLoaded()){}; //logEvent.WaitOne();
  // do something
 }  

 void webBrowser_Loaded(object sender, RoutedEventArgs e)
 {
   logEvent.Set();
 }
 void webBrowser_LoadCompleted(object sender, NavigationEventArgs e)
 {
    logEvent.Set();
 }  

您正在使用 logEvent.WaitOne() 阻塞 UI 线程,因此 LoadCompleted 事件(将在 UI 线程上下文中执行)可以永远不会被解雇。

我会写一个异步扩展方法,比如

public static class MyExtensions
{
    public static Task NavigateAsync(this WebBrowser browser, Uri  uri)
    {
        var tcs = new TaskCompletionSource<object>();
        LoadCompletedEventHandler loadCompleted = null;

        loadCompleted = (s, e) =>
            {
                browser.LoadCompleted -= loadCompleted;
                tcs.SetResult(e.WebResponse);
            };

        browser.LoadCompleted += loadCompleted;
        browser.Navigate(uri);

        return tcs.Task;
    }
}

并像

一样使用它
await webBrowser.NavigateAsync(firstURI);
await webBrowser.NavigateAsync(secondURI);