C# 如何使用C检测WPF中UI线程何时启动和停止处理?

C# 如何使用C检测WPF中UI线程何时启动和停止处理?,c#,.net,wpf,multithreading,user-interface,C#,.net,Wpf,Multithreading,User Interface,在我的WPF C应用程序中,我有一个小圆圈动画,在处理过程中显示,让用户知道应用程序正在思考,他们应该冷静下来。这是一个单独的exe。因此,例如,当用户单击一个按钮来运行分析时(可能需要5-10秒),我启动该过程以显示动画,当全部完成时,我停止该过程。在此期间,新生成了子线程来处理后台任务。完成后,将更新UI,由于数据网格复杂,这可能需要几秒钟的时间 虽然这在技术上是可行的,但我宁愿用另一种方式来处理它。我宁愿让应用程序在线程工作时自动检测并自动显示动画,当线程全部完成时,它停止显示动画。我可以

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

虽然这在技术上是可行的,但我宁愿用另一种方式来处理它。我宁愿让应用程序在线程工作时自动检测并自动显示动画,当线程全部完成时,它停止显示动画。我可以很容易地检测到后台线程,但是如何检测UI线程呢?我宁愿这样做,因为有几次我不小心错过了终止应用程序,并且在处理完成后它仍在运行。这将防止这种情况发生

UI线程启动和停止时是否会触发事件?如果没有,假设我在那里抛出了一个每1/2秒触发一次的计时器,是否有一个调用可以告诉我UI线程的状态


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


实际上,在所有情况下,您都应该将长时间运行的任务移动到另一个后台线程,而不是在UI线程中执行这些任务。您可以在这些任务开始时显式禁用窗体上的某些/所有控件,并在任务结束时启用它们。我强烈建议您不要阻止UI线程作为禁用表单的一种手段,因为从用户的角度来看,它似乎是由于编程错误导致程序无法工作,而不是认为它是所需的行为。

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


实际上,在所有情况下,您都应该将长时间运行的任务移动到另一个后台线程,而不是在UI线程中执行这些任务。您可以在这些任务开始时显式禁用窗体上的某些/所有控件,并在任务结束时启用它们。我强烈建议您不要阻止UI线程作为禁用表单的一种手段,因为从用户的角度来看,它看起来似乎是由于编程错误导致程序无法工作,与认为这是期望的行为相反。

更好的方法是将处理移出UI,例如使用,并让后台工作人员将通知发布到UI线程启动、进度更新和完成


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

更好的方法是将处理移出UI,例如,使用,并让后台工作人员将通知发布到UI线程启动、进度更新、完成


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

您可以尝试通过应用程序的Dispatcher以极低的优先级向主UI线程添加任务:


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

您可以尝试通过应用程序的调度程序,以极低的优先级向主UI线程添加任务:


这基本上是说,当主UI线程完全没有更好的事情要做时,调用StopAnimation。诀窍是找到合适的时间调用.BeginInvoke-就在网格加载之前或加载期间。

如果您向我们展示您目前的情况,我们可能会建议不同的替代方案?很难改进我们看不到的代码:您最好使用BackgroundWorker并在那里运行耗时的流程。因此,您可以在DoWork之前启动动画,并在RunWorkerCompletedUI中停止动画。我始终在主应用程序的线程中工作。您可以在不同的线程后台工作人员、任务等中执行任何长操作。我可能没有很好地解释这一点。大部分处理是在后台任务上进行的。最后会发生一些UI线程处理,这是由于多个选项卡上的大量数据网格会被重新加载,这可能需要几秒钟才能完成。我的动画是一个独立的

ate exe,并且未在UI线程上运行。我知道如何检测后台线程的状态,但我想知道如何检测UI线程的状态。这样,当所有线程都完成时,我可以停止动画。如果您向我们展示您目前的情况,我们可以建议不同的替代方案吗?很难改进我们看不到的代码:您最好使用BackgroundWorker并在那里运行耗时的流程。因此,您可以在DoWork之前启动动画,并在RunWorkerCompletedUI中停止动画。我始终在主应用程序的线程中工作。您可以在不同的线程后台工作人员、任务等中执行任何长操作。我可能没有很好地解释这一点。大部分处理是在后台任务上进行的。最后会发生一些UI线程处理,这是由于多个选项卡上的大量数据网格会被重新加载,这可能需要几秒钟才能完成。我的动画是一个单独的exe,不在UI线程上运行。我知道如何检测后台线程的状态,但我想知道如何检测UI线程的状态。这样,当所有线程完成后,我可以停止动画。我的动画是一个单独的exe,设置为始终在顶部。因此,即使使用了UI线程,动画也会立即启动和停止,并正确地设置动画。我经常在后台线程中运行长时间运行的任务,但我不希望用户在处理过程中做任何事情,因为我还需要重新加载数据网格和更新控件等。因此,它们不应该能够与UI交互。@Nullqwerty然后像我说的那样显式禁用UI。即使您禁用数据网格、按钮等,作为用户,无法执行诸如移动窗口、退出程序、最小化应用程序、从页面中选择一些文本等操作,这真的很烦人,因为它已冻结。禁用您需要的功能,并保留其余功能。感谢您的回复。实际上我是这样做的。那不是我的问题。我的问题是,我如何检测UI线程的状态,因为我想让动画自动启动和停止?@Nullqwerty我的意思是,任何时候你的UI线程被阻塞足够长的时间,让人注意到这是你的应用程序的故障,应该进行修复,以避免它发生,而不是动态显示微调器。我的数据网格必须加载。每个数据网格绑定只需1秒以上,考虑到它是一个telerik网格,有总计和分组,这并不坏。有6个网格,所以大约5秒。UI不会冻结、停止响应或做任何不好的事情。那不是我的问题。如果你不知道我的问题的答案,谢谢。我的动画是一个单独的exe,设置为始终在顶部。因此,即使使用了UI线程,动画也会立即启动和停止,并正确地设置动画。我经常在后台线程中运行长时间运行的任务,但我不希望用户在处理过程中做任何事情,因为我还需要重新加载数据网格和更新控件等。因此,它们不应该能够与UI交互。@Nullqwerty然后像我说的那样显式禁用UI。即使您禁用数据网格、按钮等,作为用户,无法执行诸如移动窗口、退出程序、最小化应用程序、从页面中选择一些文本等操作,这真的很烦人,因为它已冻结。禁用您需要的功能,并保留其余功能。感谢您的回复。实际上我是这样做的。那不是我的问题。我的问题是,我如何检测UI线程的状态,因为我想让动画自动启动和停止?@Nullqwerty我的意思是,任何时候你的UI线程被阻塞足够长的时间,让人注意到这是你的应用程序的故障,应该进行修复,以避免它发生,而不是动态显示微调器。我的数据网格必须加载。每个数据网格绑定只需1秒以上,考虑到它是一个telerik网格,有总计和分组,这并不坏。有6个网格,所以大约5秒。UI不会冻结、停止响应或做任何不好的事情。那不是我的问题。如果你不知道我的问题的答案,谢谢。后台任务通常在单独的后台线程中。但一旦完成,不同选项卡上的大量大型数据网格必须重新加载,这将在ui线程上。仅仅这一步通常需要几秒钟,这是另一个问题和错误。您不希望一次加载数据。有两个原因:第一,它降低了用户体验-没有人喜欢慢程序;其次,分页和搜索可以很好地完成这项工作——您一次只加载少量数据,并允许用户搜索和浏览页面。以谷歌为例。给定一个搜索查询,它将返回10个最相关的结果。它永远不会返回与查询匹配的所有PB。请注意我是
不想批评,这和我之前犯的错误完全一样。我知道你不想批评,我感谢你的帮助。当我说大数据网格时,我不是说行数。我说的是页脚,有总计和多个分组,这是一个telerik网格。分页无助于解决此问题。电网已尽可能优化,telerik支持会议证实了这一点。加载每个网格大约需要0.75-1.25秒,我有五个网格。用户群一致表示,他们希望所有网格一次加载,而不是在切换选项卡时让网格加载而造成延迟。后台任务通常位于单独的后台线程中。但一旦完成,不同选项卡上的大量大型数据网格必须重新加载,这将在ui线程上。仅仅这一步通常需要几秒钟,这是另一个问题和错误。您不希望一次加载数据。有两个原因:第一,它降低了用户体验-没有人喜欢慢程序;其次,分页和搜索可以很好地完成这项工作——您一次只加载少量数据,并允许用户搜索和浏览页面。以谷歌为例。给定一个搜索查询,它将返回10个最相关的结果。它永远不会返回与查询匹配的所有PB。请注意,我不是想批评,这与我之前犯的错误完全相同。我理解你不是想批评,我感谢你的帮助。当我说大数据网格时,我不是说行数。我说的是页脚,有总计和多个分组,这是一个telerik网格。分页无助于解决此问题。电网已尽可能优化,telerik支持会议证实了这一点。加载每个网格大约需要0.75-1.25秒,我有五个网格。用户群一致表示,他们希望所有网格一次加载,而不是在切换选项卡时让它们加载而经历延迟。
Application.Current.Dispatcher.BeginInvoke((ThreadStart)StopAnimation, DispatcherPriority.ApplicationIdle);

...

private void StopAnimation()
{
    ...
}