我知道这有been asked before,但我认为these solutions不灵活。 DocumentCompleted
事件应该用于确定负载何时完成,而不是用于执行工作的方法。如果您需要执行几个不同的任务,每个任务必须多次导航,将逻辑放在DocumentCompleted
事件中会将其变成一个难以阅读和维护的凌乱的交换机/案例路由器。
你需要在你的方法执行导航期间可以实际等待的东西,这样你就可以用你已经存在的方法继续你的任务。我的第一个是实际的Wait()方法。
我认为这样的事情很接近:
void WaitForLoad()
{
isLoading = true;
while (isLoading)
{
if (Application.Current == null) break;
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, (DispatcherOperationCallback)delegate(object unused) { return null; }, null);
}
}
并在DocumentCompleted
事件中将Isloading设置为false。
您应该能够在任何导致页面加载的操作之后调用此方法。它有效,它有一些问题。
1)它将应用程序的CPU使用率最多发送到35%,直到页面加载完毕,即使没有其他任何事情发生。
2)如果应用程序在其运行时尝试关闭,则循环将继续运行并且在没有窗口的情况下打开应用程序,因此当应用程序为空时需要中断。
这可以修复,还是我会以错误的方式来到这里?
编辑:我尝试在下面实施ManualResetEvent解决方案,但它导致了其他一些我不确定可以解决的问题,而不会造成比上面更糟糕的情况。由于WebBrowser在UI上,因此锁定线程会停止整个应用程序。如果工作在后台线程上完成,则可以锁定,但随后访问WebBrowser变得非常困难。
答案 0 :(得分:2)
在您的情况下,听起来您希望在等待加载文档时阻止特定线程。在这种情况下,你会做这样的事情:
protected ManualResetEvent _resetEvent = new ManualResetEvent(false);
public void WaitingThread()
{
_resetEvent.WaitOne();
// Do stuff after the web browser completes.
}
public void LoadWebPage()
{
webBrowser.Navigate(new Uri(url));
webBrowser.DocumentCompleted = (s, e) => { _resetEvent.Set(); };
}
基本上,当文档完成时,您会发出事件信号,并且等待事件的所有线程都会解锁并继续执行。
答案 1 :(得分:0)
我注意到你使用Dispatcher.CurrentDispatcher.Invoke
这对调用你的方法很有用,它以某种方式从另一个线程更新UI。但是从提供的代码中,我看不到其他线程中的任何代码然后是UI。所以
在另一个线程上运行该代码。
在应用程序的关闭事件中,您可以isLoading=false;
等等,如果调用的方法是长期运行的东西插入
如果(!isLoading) 返回;
//或以其他适合的方式破解执行
编辑:
更好的方法是在多线程中处理这个,然后只是简单地继续布尔变量,使用一些Synchonization object