【问题标题】:Task updating properties on Main thread主线程上的任务更新属性
【发布时间】:2014-03-03 12:50:49
【问题描述】:

我正在尝试更新绑定到 ProgressBar 的主线程上的属性。在 viewmodel 中,我有下面的代码,它不起作用。

TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

Task task = Task.Factory.StartNew(() =>
{
    DoLongRunningWork();

}).ContinueWith(_=>
{   

    ApplicationStatus = "Task finished!";

}, TaskScheduler.FromCurrentSynchronizationContext());


DoLongRunningWork()
{
    // Alot of stuff

    Task.Factory.StartNew(() =>
    {
        ProgressBarValue += progressTick;
    }).Start(uiScheduler);
}

【问题讨论】:

  • 解释not working
  • ProgressBarValue += progressTick;没有更新
  • 哪个版本的框架?以及ProgressBarValueprogressTick的变量类型是什么?
  • 您正在更新另一个任务中的ProgressBarValue。它应该由 UI 线程更新。或者你应该使用SomeControl.Invoke BTW:外部任务立即完成,因为它只创建另一个任务(做实际工作)然后完成
  • Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => ProgressBarValue += progressTick)); 在此答案中:stackoverflow.com/a/1644254/2609288

标签: c# multithreading task-parallel-library task


【解决方案1】:

如果属性 ProgressBarValue 绑定到 WPF 元素,则唯一可以更新 ProgressBar 的线程就是创建它的线程。

所以,我的假设是包含ProgressBarValue 的类也实现了INotifyPropertyChanged。这意味着您有一些引发事件PropertyChanged 的逻辑。

我会创建一个引发事件的方法,并且总是使用Dispatcher。 (Dispatcher 允许您在创建 WPF 控件的线程上调用函数。)

private void raisePropertyChanged(string name)
{
  Dispatcher.InvokeAsync(()=>
  {
    if(PropertyChanged != null)
      PropertyChanged(this, new PropertyChangedEventArgs(name));
  });
}

这将始终在正确的线程上更新ProgressBar

【讨论】:

  • 这个属性以及整个类已经实现了 INotifyPropertyChanged
  • 那么您只需在引发PropertyChanged 事件时使用Dispatcher
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多