MultiProgressViewModel用于观察复杂算法中的进度





5.00/5 (4投票s)
我最近发表了一篇关于ProgressViewModel的文章,展示了一个可用于C# 4.0中后台处理的软件设计。这篇文章扩展了这个设计,增加了输出多个进度的能力。
引言
管理异步任务并将它们与响应式GUI连接一直是过去的挑战。多核处理器的出现和C#中的并行任务库为我们提供了改进算法以提高速度和效率的工具。Async CTP和C# 5.0尚未正式发布,因此寻找一个可应用于C# 4.0的稳定ProgressViewModel
是值得的。我在这篇CodeProject文章中开发了这个ViewModel,题为一个可重用的ProgressViewModel,用于通过MVVM观察进度。
本文在前文展示的设计基础上进行了扩展,以便在此模式下管理多个进度。
StyleCop
我在项目中使用了StyleCop,以确保代码的统一性和可读性。因此,如果您在编译项目时遇到错误,可以下载并安装StyleCop,或者编辑/删除每个.csproj文件中的相应条目。
<Import Project="$(ProgramFiles)\MSBuild\StyleCop\v4.5\StyleCop.Targets" />
背景
我正在开发一个需要批量处理的应用程序。选中N个项目,然后(按顺序)在异步执行的线程中处理每个项目。为了模拟这种情况,我扩展了演示应用程序,使其不仅解析给定目录中的HTML文件,还解析Path目录下的所有子目录中的所有HTML文件。
进度部分有两个进度指示器。右上方MainWindow上的n of m标签和进度条。前者指示已解析的目录及其总数,而后者进度条(如前所述)指示解析任何给定目录中HTML文件的进度。
如果您系统中没有包含HTML文件和更多HTML文件的子目录的目录,请下载附带的SampleData。点击第一个MainWinidow底部的展开器,将应用程序指向解压缩的文件夹,然后点击Process HTML按钮开始处理。
Using the Code
这里讨论的ProgressViewModel
的扩展(简而言之)在MultiProgressVM
类中,我用数组替换了简单的属性
ProgressMin
ProgressMax
ProgressValue
, andIsProgressVisible
替换为数组
ProgressMin[]
ProgressMax[]
ProgressValue[]
, andIsProgressVisible[]
类构造函数接受一个int
数字,该数字控制这些数组的大小(默认为一)。然后,视图可以通过绑定到数组中每个属性的项来实现多个进度指示器。我希望将此扩展与第一种方法分开,因为我希望确保之后能看到差异,并且我仍然希望使用第一个ProgressViewModel
文章中的方法。
![]() |
Visual Studio 2010解决方案资源管理器中的项目概述显示,与之前发布的关于 我在每个层(除了视图和结果类)中为每个对象添加了一个额外的类。这再次展示了这里使用的架构的分层性质。 视图中的绑定已从
以指示数组中的相应项。 在 this.ProgressMax = files.Length;
被替换为 this.SetMaxValue(1, files.Length);
让绑定的UI知道这些值确实已经改变了。 |
MultiProcessHTML
类中的ProcessHTMLDirectory
方法会迭代一个内循环和一个外循环。内循环遍历给定目录中的每个文件,外循环遍历给定目录中的每个目录。
关于这一点,没什么更多要说的了,只是强调上述差异,并指出ProgressViewModel
现在管理两个进度指示器,而以前只有一个。如果您觉得上面的解释过于简短,请务必阅读我关于ProgressViewModel
的第一篇文章。
关注点
我不确定数组是否可以绑定到UI元素。简短的回答是肯定的,但由于C#不支持命名索引器,我们无法再通过CLR属性更新值,并且在值更改时需要执行OnPropertyChanged()
。因此,在这种情况下,我通过为每个数组属性实现一个单独的方法并将每个数组属性的setter设置为private
来实现(我认为实现一个带有索引器的单独类有点跑题,不值得费力)。
看到新的n of m进度指示器,我开始考虑估计进度指示器,例如:剩余时间:x分钟。一个简单的方法是记录执行一个内循环所需的时间,然后乘以剩余内循环的数量。如果每个循环平均需要相同的时间,这将很好地工作。
如果每个内循环的处理工作量差异很大,那么它将无法很好地工作。显然,在这种情况下,获得可靠的估计是另一个独立的问题。也许这是本系列第三篇文章的主题……
请花点时间通过投票和评论给我您的反馈。
历史
- 2012年1月20日:第一个版本。