首页 文章

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

提问于
浏览
6

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

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

UPDATE:

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

3 回答

  • 6

    Dispatcher . Dispatcher维护特定线程的优先级工作项队列 . 这可能有助于您更新UI . 如果你有很多与UI相关的初始化,那么这将无法帮助你 .

    Dispatcher实际上并不总是替代BackgroundWorker . 最佳做法是根据您的要求选择更合适的一种 . 例如,如果您希望在不排队的情况下执行某些操作,那么BackgroundWorker就是解决方案 . 另一方面,如果排队不是问题,那么Dispatcher是另一种选择 . 例如,Dispatcher正在使用拼写检查程序和语法突出显示功能 .

    WPF线程模型所有WPF应用程序都以两个重要线程开始,一个用于呈现,另一个用于管理用户界面 . 渲染线程是一个在后台运行的隐藏线程,因此您通常处理的唯一线程是UI线程 . WPF要求将其大多数对象绑定到UI线程 . 这称为线程关联,这意味着您只能在创建它的线程上使用WPF对象 . 在其他线程上使用它将导致抛出运行时异常 . 请注意,WPF线程模型与基于Win32®的API可以很好地互操作 . 这意味着WPF可以由任何基于HWND的API(Windows窗体,VisualBasic®,MFC甚至Win32)托管或托管 . 线程关联性由Dispatcher类处理,Dispatcher类是WPF应用程序的优先级消息循环 . 通常,您的WPF项目具有单个Dispatcher对象(因此是单个UI线程),所有用户界面工作都通过该对象进行引导 .

    注意 :

    Dispatcher和其他线程方法之间的主要区别在于Dispatcher实际上并不是多线程的 . Dispatcher控制控件,这需要一个线程才能正常运行; Dispatcher的BeginInvoke方法将事件排队等待以后执行(取决于优先级等),但仍在同一个线程上 .

    有关更多信息,请参见this thread .

  • 0

    您还可以使用线程池对项目进行排队并运行这样的任务,但要小心,如果您的任务需要在完成后更新UI,则必须将数据封送回UI线程 .

  • 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

相关问题