+-
带有Dispatcher的BackgroundWorker似乎什么也没做
我正在尝试更新ObservableCollection,它是绑定到UI的数据.我知道要做到这一点,我需要使用Dispatcher和BeginvInvoke()并进行设置,以使UI不会在冻结时冻结,使用BackgroundWorker是解决该问题的好方法.无论如何,我已经编译并运行了所有这些东西,但是什么也没有发生.我需要每2分钟左右更新一次UI,所以我也使用了DispatcherTimer

这是可行的,因为DispatcherTimer是Dispatcher的一部分,但是冻结了UI:

DispatcherTimer dispTimer = new DispatcherTimer();
dispTimer.Tick += dispTimer_Tick;
dispTimer.Interval = new TimeSpan(0, 0, 45);
dispTimer.Start();

private void dispTimer_Tick(object sender, EventArgs e)
{
    PartialEmployees.Clear();          
}

因此,使用BackgroundWorker我将其拼凑而成:

DispatcherTimer dispTimer = new DispatcherTimer();
dispTimer.Tick += dispTimer_Tick;
dispTimer.Interval = new TimeSpan(0, 0, 45);
dispTimer.Start();

private void dispTimer_Tick(object sender, EventArgs e)
{
    BackgroundWorker _worker = new BackgroundWorker();
    _worker.DoWork += DoWork;            
    _worker.RunWorkerAsync();

}

private void DoWork(object sender, DoWorkEventArgs e)
{            
    Dispatcher.CurrentDispatcher.BeginInvoke( new Action(()=> 
        {
            PartialEmployees.Clear();
        }));
} 

但是,UI没有任何反应.我缺少什么/做错了什么?

最佳答案
您有两个问题:

>从后台线程使用Dispatcher.CurrentDispatcher时,它将获取后台线程的Dispatcher,而不是UI线程的Dispatcher.
>从您的描述中,我发现您的PartialEmployees.Clear()方法需要花费大量时间来执行,并且您希望避免在执行期间锁定UI线程.但是,让BackgroundWorker在UI线程上调用PartialEmployees.Clear()将具有与使用DispatcherTimer相同的效果,因此您需要的解决方案与您要使用的解决方案不同.

如果只想解决Dispatcher.CurrentDispatcher问题,只需将当前Dispatcher存储在这样的局部变量中:

private void dispTimer_Tick(object sender, EventArgs e) 
{
  var uiDispatcher = Dispatcher.CurrentDispatcher;

  BackgroundWorker _worker = new BackgroundWorker(); 
  _worker.DoWork += (sender, e) =>
    uiDispatcher.BeginInvoke(new Action(() =>
    {
      PartialEmployees.Clear();
    }));
  _worker.RunWorkerAsync(); 
} 

这将使您的UI更改生效,但仍将在更改期间锁定UI,就像您没有使用BackgroundWorker一样.原因是:

> DispatcherTimer触发,在UI线程上执行.它所做的全部(dispTimer_Tick)是启动BackgroundWorker,然后退出.
> BackgroundWorker自己执行therad.它所做的只是调度Dispatcher回调,然后退出.
> Dispatcher回调再次在UI线程上执行.它调用PartialEmployees.Clear()会花费一些时间,并在执行时锁定UI线程.

因此,您的行为与DispatcherTimer回调直接调用PartialEmployees.Clear()相同:在每种情况下,耗时的操作都在UI线程上执行.

锁定的原因是,每当您在UI线程上进行大量工作时,都会在运行时得到瞬时锁定.解决方案是将您的工作分成较小的部分,然后一次从DispatcherTimer或BackgroundWorker中一次完成.在您的情况下,检查PartialEmployees.Clear()的代码以查看是否可以增量执行.

点击查看更多相关文章

转载注明原文:带有Dispatcher的BackgroundWorker似乎什么也没做 - 乐贴网