【发布时间】:2019-02-11 15:14:14
【问题描述】:
我想在我的 WPF 应用程序中循环更新某些 UI 元素的位置。每次迭代后,应重新渲染 UI 以使更改可见。可以使用 CancellationToken 随时停止更新过程。由于取消是由用户执行的,因此 UI 必须保持对输入的响应。为此,我编写了以下方法:
public async Task DoStuff(CancellationToken token)
{
do
{
DoLayoutUpdate();
await Dispatcher.Yield(DispatcherPriority.Input);
} while (!token.IsCancellationRequested);
}
这主要是可行的:每次迭代后都会重新呈现 UI,我可以单击按钮取消操作,因此输入也可以正常工作。问题是:如果没有输入并且没有要重新渲染的内容,该方法就会卡在 Yield 中。大概是线程被阻塞等待输入或渲染任务。
如果我将 DispatcherPriority 增加到 Render,则该方法不会再卡住,但 UI 不会更新并且输入不再处理。
我该如何解决这个问题?
【问题讨论】:
-
你试过
await Task.Delay(10);或await Dispatcher.BeginInvoke(new Action(() => { }), System.Windows.Threading.DispatcherPriority.Input);吗? -
换句话说,您的问题是如何检查调度程序队列是否为空? Dispatcher 是PriorityQueue,那会相当复杂。看来您正在尝试实现DoEvents(),这是错误技术。而是将您的工作分成合理的任务并调用它们,很难推荐更具体的没有细节的东西。你在做游戏什么的 - 有一个way
-
为什么在代码中更新布局而不是使用例如animated transforms?
-
@PanagiotisKanavos 我不能使用动画变换,布局很重要,需要手动重新计算。
-
@mm8 这两个似乎都可以正常工作。如果你把它变成答案,我会把它标记为正确的。
标签: c# .net wpf dispatcher