有没有在WPF中使用Background Worker的替代方法?

时间:2011-08-10 02:19:55

标签: c# .net wpf multithreading backgroundworker

我是WPF的初学者,在我的应用程序中,我需要执行一系列初始化步骤,这些步骤需要10-15秒才能完成,在此期间我的UI变得无法响应。

我昨天使用后台工作人员,但它没有更新我的窗口,事实上它被冻结了。不确定,但也许它不起作用,因为此控件仅适用于Windows窗体。

更新

如果没有太多麻烦,你能给我一个例子来使用替代方案吗?对于我的情况,程序将从数据库中获取一些值。

3 个答案:

答案 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