【问题标题】:How to update a property on the viewmodel before calling a long running process?如何在调用长时间运行的进程之前更新视图模型上的属性?
【发布时间】:2017-09-09 07:38:13
【问题描述】:

我有以下代码:

Public Sub ExecuteMyCommand
   ShowProgressBar=True
   CallLongRunningProcess
   ShowProgressBar=False
End Sub

要让 UI 中的进度条在长时间运行的进程开始之前实际显示,必须将这段代码重写为:

Public Async Sub ExecuteMyCommand
   ShowProgressBar=True
   Await Task.Run(Sub() CallLongRunningProcess)
   ShowProgressBar=False
End Sub

现在的问题:

在某些方法中,长时间运行的过程涉及创建 WPF 用户控件。这些必须在 STA 线程上创建。我已经找到了如何做到这一点,但后来我得到了一个 InvalidOperationException,因为用户控件归非 UI 线程所有。所以,我正在寻找一种在调用 UI 线程上长时间运行的进程之前更新 ShowProgressBar 属性的方法(是的,丑陋,我知道)。

【问题讨论】:

  • “所以,我正在寻找一种在 UI 线程上调用长时间运行的进程之前更新 ShowProgressBar 属性的方法”是什么意思,它只是一个布尔值,更新是什么意思?
  • @Sybren ShowProgressBar 属性绑定到视图中的 ProgressBar.Visibility 属性。抱歉,如果不清楚。

标签: wpf multithreading mvvm


【解决方案1】:

您尝试过 Dispatcher.Invoke 吗?它将任务保留在 UI 线程上。 当然,您必须将 ShowProgressBar=False 移动到委托中。

Public Sub ExecuteMyCommand
    ShowProgressBar=True
    Me.Dispatcher.Invoke(DispatcherPriority.Normal, New LongRunningProcessDelegate())
End Sub

我还将UI修改逻辑从计算任务中分离出来,即任务完成后应该回调到UI线程中,UI元素的修改将留给回调。

【讨论】:

  • 当我在异步数据库查询完成后必须刷新 UI 时,它对我来说效果很好,我想知道你的情况有什么不同。我正在做 C#。当然,繁重的计算是由后台工作人员完成的。我永远不会给 UI 线程带来负担。
  • 我很抱歉。你的解决方案对我有用。我之前的做法一定略有不同。
猜你喜欢
  • 2013-09-14
  • 1970-01-01
  • 1970-01-01
  • 2012-05-22
  • 1970-01-01
  • 1970-01-01
  • 2011-07-04
  • 2015-04-18
  • 2020-07-01
相关资源
最近更新 更多