2

在我的 WPF C# 应用程序中,我在处理事情时显示了一个小圆圈动画,让用户知道应用程序正在“思考”,他们应该冷静下来。这是一个单独的exe。因此,例如,当用户单击一个按钮以运行分析(可能需要 5-10 秒)时,我会启动显示动画的过程,当一切完成时,我会停止该过程。在此期间,新产生了子线程来处理后台任务。完成后,UI 会更新,由于复杂的数据网格,这可能需要几秒钟。

虽然这在技术上有效,但我宁愿以不同的方式处理它。我宁愿让应用程序自动检测线程何时工作并自动显示动画,当线程全部完成时,它会停止显示它。我可以轻松检测到后台线程,但如何检测 UI 线程?我宁愿这样做,因为有几次我不小心错过了杀死应用程序,并且在处理完成后它仍在运行。这将阻止这种情况。

UI 线程启动和停止时是否会触发事件?如果没有,假设我在其中放置了一个每 1/2 秒触发一次的计时器,是否可以拨打电话告诉我 UI 线程的状态?

谢谢

4

3 回答 3

2

更好的方法是处理移出 UI(例如,BackgroundWorker让后台工作人员将通知发布到 UI 线程(开始、进度更新、完成)。

不要重新发明轮子并将处理逻辑移出 UI 线程。

于 2013-01-10T15:01:47.173 回答
1

这是第 22 条规则。如果您有一些代码可以运行以确定 UI 线程被阻塞,那么您将无法启动动画,因为 UI 线程被阻塞;直到 UI 线程完成它一直在处理的任务之后,动画才会显示,此时动画不再相关。

在几乎所有情况下,您都应该将长时间运行的任务转移到另一个后台线程,而不是在 UI 线程中执行它们。您可以在此类任务开始时明确禁用表单上的部分/所有控件,并在结束时启用它们。我 强烈建议您不要阻止 UI 线程作为禁用表单的一种方式,因为从用户的角度来看,它看起来好像程序由于编程错误而无法运行,而不是认为它是所需的行为。

于 2013-01-10T15:01:12.817 回答
1

您可以尝试通过应用程序将任务添加到具有非常低优先级的主 UI 线程Dispatcher

Application.Current.Dispatcher.BeginInvoke((ThreadStart)StopAnimation, DispatcherPriority.ApplicationIdle);

...

private void StopAnimation()
{
    ...
}

这基本上是说“当主 UI 线程完全没有更好的事情可做时,调用 StopAnimation()”。诀窍是找到正确的调用时间.BeginInvoke——就在网格加载之前或期间。

于 2013-01-10T23:39:22.937 回答