如何让一个类中的长时间运行的方法向C#中的调用类报告其进度?
我有一个方法可以处理数千个项目,而且需要很长时间 什么是“正确”的方法,让正在执行长操作的方法在执行此操作时报告其进度 例如,如果我想让UI中的进度条显示另一个线程中某个长时间运行的方法的进度。请使用进度条 在BackgroundWorker上有几个SO问题,例如:如何让一个类中的长时间运行的方法向C#中的调用类报告其进度?,c#,.net,C#,.net,我有一个方法可以处理数千个项目,而且需要很长时间 什么是“正确”的方法,让正在执行长操作的方法在执行此操作时报告其进度 例如,如果我想让UI中的进度条显示另一个线程中某个长时间运行的方法的进度。请使用进度条 在BackgroundWorker上有几个SO问题,例如: 在这种特殊情况下,我倾向于创建一个自定义事件,并从长时间运行的流程中触发它,然后在事件处理程序中订阅要更新到事件的任何UI元素。(UI始终在主UI线程中更新)长时间运行的任务(无论是否在专用后台线程中运行)可能希望通过以下两种方
- 报告进度(对于BackgroundWorker,这对应于调用
)BackgroundWorker.ReportProgress
- 检查是否已请求取消(与BackgroundWorker一起,这对应于检查
属性)CancellationPending
IProgress
,该接口使用方法ReportProgress
和属性CancellationPending
来抽象此功能。我有一个实现这个接口的BackgroundWorker的增强版本,还有一些不使用BackgroundWorker的替代实现
例如,控制台应用程序可能在前台运行长时间运行的任务。其IProgress.ReportProgress
的实现,例如,如果在详细模式下运行,可以使用Console.WriteLine
。它的IProgress.CancellationPending的实现可以检查是否按下了CTRL-C。可以从此控制台应用程序和使用BackgroundWorker的WinForms应用程序调用相同的长时间运行任务
我个人认为,在设计BackgroundWorker时,这样的抽象应该包含在.NET框架中。仅仅更新UI不是有点浪费吗?对于拆分长时间运行的进程并使其线程化,而不是简单地从一个长时间运行的进程报告,这难道不是一个更好的解决方案吗?自定义事件有一个缺点,即它们需要被封送到订阅服务器的线程,这需要编写几行额外的代码。但是BackgroundWorker可以很好地为您处理这个问题。我怀疑仅仅在锁定的UI上有一个进度条会安抚用户,所以我认为可以安全地假设OP也需要一个单独的线程。@Aviad,@ProfK,听说过KISS吗?BackgroundWorker并不是关于长时间运行代码的所有问题的答案。很高兴看到其他人(即Tim)也意识到还有其他选择。“UI总是在主线程中更新”——这不是自动的。您需要使用Control.Invoke来更新从后台线程触发的事件处理程序中的UI元素。或者找一个后台工作人员帮你解决这个问题。