暂停程序流直到 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);
我必须使用 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);