我正在尝试重用UserControl并借用一些跟踪进度的逻辑。我会尝试简化一些事情。 MyWindow.xaml包含一个MyUserControl。 MyUserControl有自己的进度指示器(正在格式化...,复制文件......等),我想在MyWindow表单中的某个地方镜像这个进度。但是,用户控件有一些我不太了解的逻辑。我已阅读并阅读,但我仍然不理解调度员。以下是用户控件中更新进度的逻辑摘要。
this.Dispatcher.Invoke(DispatcherPriority.Input, (Action)(() =>
{
DAProgressIndicator = InfiniteProgress.AddNewInstanceToControl(StatusGrid, new SolidColorBrush(new Color() { A = 170, R = 128, G = 128, B = 128 }), string.Empty);
DAProgressIndicator.Message = MediaCardAdminRes.ActivatingCard;
ActivateInProgress = true;
}));
我认为我很聪明,并在MyUserControl中添加一个事件,该事件将在ActivateInProgress属性集逻辑中调用。
public bool ActivateInProgress
{
get
{
return _activateInProgress;
}
set
{
_activateInProgress = value;
if (ActivateInProgressHandler != null)
{
ActivateInProgressHandler(value);
}
}
}
我将MyWindow构造函数中的ActivateInProgressHandler设置为以下方法,该方法设置用于窗口自身进度指示器的视图模型属性。
private void SetActivation(bool activateInProgress)
{
viewModel.ActivationInProgress = activateInProgress;
}
但是,窗口的进度指示器永远不会改变。所以,我确信Dispatcher.Invoke正在做一些我不理解的事情。如果我在SetActivation方法中放置一个消息框,则更新线程块和窗口的进度指示器。我理解基本线程,但整个Dispatcher对我来说都是新的。我错过了什么?
更新:现在似乎正在运作。事实证明,进展正在快速更新,以至于它从未在屏幕上显示过。但是,我仍然想了解为什么Dispatcher.Invoke已经完成(这是我没有写的现有代码)。为什么动作内容不与* .xaml.cs代码的其余部分一致?
答案 0 :(得分:1)
你的最后一段提到了两次线程,这就提出了有一个或多个后台线程的可能性。但是既然你没有提到应用程序中存在哪些线程,它们是如何创建的,它们如何交互等等,我现在假设只有一个线程。
如果UI线程是唯一的线程,问题显而易见:您的UI线程正在忙于运行正在进行的任务,并且没有花时间来呈现更新的UI。如果这是问题,这可能会解决它:
viewModel.ActivationInProgress = activateInProgress;
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,
new Action(() => {}));
BeginInvoke强制所有Dispatcher操作高于输入优先级,以便在当前线程继续之前完成。
答案 1 :(得分:0)
Dispatcher在队列中工作。所以它可能是UI线程阻塞。您可以通过Dispatcher在队列中添加更多工作,但它永远不会被执行,因为UI线程正在阻塞。
也许试试这个:
DispatcherFrame _frame = new DispatcherFrame();
Dispatcher.PushFrame(_frame);
这将使您的工作在工作的前面已经在队列中。因此,UI线程将完成工作,然后再次阻止。