我是WPF的初学者,在我的应用程序中,我需要执行一系列初始化步骤,这些步骤需要10-15秒才能完成,在此期间我的UI变得无法响应。
我昨天使用后台工作人员,但它没有更新我的窗口,事实上它被冻结了。不确定,但也许它不起作用,因为此控件仅适用于Windows窗体。
更新
如果没有太多麻烦,你能给我一个例子来使用替代方案吗?对于我的情况,程序将从数据库中获取一些值。
答案 0 :(得分:6)
Dispatcher。 Dispatcher维护特定线程的优先级工作项队列。这可能有助于您更新UI。如果你有很多与UI相关的初始化,那么这将无法为你提供太多帮助。
Dispatcher实际上并不总是替代BackgroundWorker。最佳做法是根据您的要求选择更合适的一种。例如,如果您希望在不排队的情况下执行某些操作,那么BackgroundWorker就是解决方案。另一方面,如果排队不是问题,那么Dispatcher是另一种选择。例如,Dispatcher正在使用拼写检查器和语法突出显示功能。
<强> WPF Thread Model 强>
所有WPF应用程序都以两个重要的线程开始,一个用于 渲染和一个用于管理用户界面。渲染 thread是一个在后台运行的隐藏线程,所以唯一 您通常处理的线程是UI线程。 WPF要求 它的大多数对象都绑定到UI线程。这被称为 线程亲和性,意味着您只能在线程上使用WPF对象 它是在哪个创建的。在其他线程上使用它将导致 要抛出的运行时异常。请注意WPF线程模型 与基于Win32®的API良好互操作。这意味着WPF可以 托管或由任何基于HWND的API托管(Windows窗体,VisualBasic®, MFC,甚至是Win32)。
线程关联性由Dispatcher处理 class,WPF应用程序的优先级消息循环。通常你的 WPF项目只有一个Dispatcher对象(因此只有一个) 所有用户界面工作的UI线程)。
注意:
Dispatcher与其他线程方法之间的主要区别 Dispatcher实际上并不是多线程的。调度员 管理控件,需要一个线程才能正常运行; Dispatcher的BeginInvoke方法将事件排队等待以后 执行(取决于优先级等),但仍然在同一个线程上。
有关详细信息,请参阅this主题。
答案 1 :(得分:0)
您还可以使用线程池对项目进行排队并运行这样的任务,但要小心,如果您的任务需要在完成后更新UI,则必须将数据封送回UI线程。 / p>
答案 2 :(得分:0)
可以使用异步委托。
http://msdn.microsoft.com/en-us/library/ms228963.aspx
确保使用以下任何与UI相关的更新:
Dispatcher.CheckAccess()
这是一个简单的例子:
private void HandleUIButtons()
{
if (!btnSplit.Dispatcher.CheckAccess())
{
//if here - we are on a different non-UI thread
btnSplit.Dispatcher.BeginInvoke(new Action(HandleUIButtons));
}
else
{
btnSplit.IsEnabled = true; //this is ultimately run on the UI-thread
}
}
从这里采取:
http://blog.clauskonrad.net/2009/03/wpf-invokerequired-dispatchercheckacces.html