问题
Im having to load a couple of pages consecutively in WPF application(.NET v4.0) with WebBrowser control and the easiest way to pause was to use a while loop and check for IsLoaded property. I was wondering if there is something better. The following SO response suggests use of AutoResetEvent but it doesn't seem to work i.e., LoadCompleted event isn't triggered and the AutoResetEvent is never set. Is there something that I've missed
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();
}
回答1:
You are blocking the UI thread with logEvent.WaitOne(), therefore LoadCompleted event (which will be executed on UI thread context) can never be fired.
I would write an async extension method like
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;
}
}
and use it like
await webBrowser.NavigateAsync(firstURI);
await webBrowser.NavigateAsync(secondURI);
来源:https://stackoverflow.com/questions/31441621/pause-program-flow-until-webbrowser-loads-a-page