在我的WPF C#应用程序中,我有一个小圆圈动画,当事情正在处理时,我会显示它,让用户知道应用程序正在“思考”,他们应该冷静下来。这是一个单独的exe。因此,例如,当用户单击一个按钮来运行分析(这可能需要5-10秒)时,我启动该过程以显示动画,当它全部完成时,我停止该过程。在此期间,新产生的子线程用于处理后台任务。完成后,将更新UI,由于复杂的数据网格,这可能需要几秒钟的时间。
虽然这在技术上是可行的,但我宁愿以一种不同的方式来处理它。我更希望应用程序在线程工作时自动检测,并自动显示动画,当所有线程都完成时,它会停止显示。我可以很容易地检测到后台线程,但是如何检测UI线程呢?我更愿意这样做,因为有几次我意外地错过了杀死应用程序,而它在处理完成后仍在运行。这将防止这种情况发生。
是否存在在UI线程启动和停止时触发的事件?如果没有,假设我抛出了一个计时器,它每1/2秒触发一次,有没有一个调用可以告诉我UI线程的状态?
谢谢
发布于 2013-01-10 23:01:47
一种更好的方法是将处理移出UI (例如,使用BackgroundWorker,并让后台工作者向UI线程发布通知(已启动、进度更新、已完成)。
不要重复发明轮子并将处理逻辑移出UI线程。
发布于 2013-01-10 23:01:13
这是个第22条军规。如果您有一些代码可以运行以确定UI线程被阻塞,那么您将无法启动动画,因为UI线程被阻塞;直到UI线程完成它一直在处理的任务之后,动画才会显示,此时动画不再相关。
在几乎所有的情况下,您都应该将长时间运行的任务移动到另一个后台线程,而不是在UI线程中执行它们。您可以在此类任务开始时显式禁用窗体上的部分/所有控件,并在结束时启用它们。我强烈建议您不要通过阻塞UI线程来禁用窗体,因为从用户的角度来看,程序看起来就像是由于编程错误而无法工作,而不是认为它是所需的行为。
发布于 2013-01-11 07:39:23
您可以尝试通过应用程序的Dispatcher将一个优先级非常低的任务添加到主UI线程中
Application.Current.Dispatcher.BeginInvoke((ThreadStart)StopAnimation, DispatcherPriority.ApplicationIdle);
...
private void StopAnimation()
{
...
}这基本上是说“当主UI线程完全没有更好的事情可做时,调用StopAnimation()”。诀窍是找到合适的时间调用.BeginInvoke -就在网格加载之前或在网格加载期间。
https://stackoverflow.com/questions/14260693
复制相似问题