带有进度条的 MVVM 异步任务






3.86/5 (5投票s)
要执行异步任务,我们将使用:1. 基于任务的异步模式 (TAP),它基于 Task 和 Task <TResult> 类型。2. MVVM 模式来执行操作。3. 进度条指示任务和子任务的进度。
引言
基于任务的异步模式 (TAP) 是一种执行异步操作的模式。在此项目中,我们将执行不返回结果 (Task) 和返回结果 (Task <TResult>) 的操作。它使用 MVVM 模式来协调任务的执行,并构建一个控件来显示任务和子任务的进度。
模式与进度
任务 - 异步
以下链接是解释任务概念的文档:异常、取消令牌、进度报告等。
http://www.microsoft.com/en-us/download/details.aspx?id=19957
MVVM 模式
项目开始时是 WPF 客户端,但由于这项技术的前景不确定,我们决定使用 Windows 客户端,因此协调进程执行的类继承自 INotifyPropertyChanged,这是 WPF 开发的惯例。项目包含了众所周知的命令实现 (IRelayCommand: ICommand)。此标准的目的是将属性和行为链接到客户端控件。数据绑定在 WPF 中运行良好,但在 Windows 应用程序中却不行,需要其他策略来以进度形式呈现数据。
任务进度
进度显示在 Windows 控件中,分为 3 个区域。
-
任务进度:此面板显示任务名称、当前项以及每个任务项的执行时间。
-
子任务进度:显示的数据与上一面板相同。
-
命令按钮:允许启动、暂停、取消执行或关闭窗口。
如何使用代码
这里将解释组成解决方案的项目:Asimatica.TaskAsyn 以及如何实现新解决方案。
MVVM 模式项目
项目 Asimatica.FW.MvvmTask 实现 MVVM 模式,其中最重要的类是:AbstractViewModel。
public abstract class AbstractViewModel : INotifyPropertyChanged, IDisposable
public abstract class AbstractViewModel : INotifyPropertyChanged, IDisposable
任务项目
项目 Asimatica.FW.AsynTask 是一个异步执行任务的库,最重要的类是:
接口 ITaskManagement
定义了异步运行任务的契约。
public interface ITaskManagement<TArgument, TResult, TProgress>
类 TaskManagement
实现了 ITaskManagement 接口。核心在于存储用于异步执行的业务规则方法的属性,该方法可以有或没有执行参数,并且可以返回结果或不返回结果。
Func<ITaskManagement<TArgument, TResult, TProgress>, TArgument, Task> DoTaskAsync Func<ITaskManagement<TArgument, TResult, TProgress>, Task> DoTaskWithouParameterAsync Func<ITaskManagement<TArgument, TResult, TProgress>, TArgument, Task<TResult>> DoTaskResultAsync Func<ITaskManagement<TArgument, TResult, TProgress>, Task<TResult>> DoTaskResultWithouParameterAsync
存在两种类型的任务方法:不返回任何内容和返回值的任务。任务可以有一系列操作,例如一个月的 30 天,每个项目都可以抛出一个子任务周期,而这个子任务周期本身也可以有自己的进度周期,因此您会发现 Task 和 Subtask 成员。
public Task RunAsync(TArgument parameter) { DateTime dtStart; if (IsBusy) { return null; } dtStart = DateTime.Now; InitilizeRun(dtStart); var task = DoTaskAsync(this, parameter); if (this.Scheduler == null) { task.ContinueWith(t => TaskCompleted(task, dtStart)); } else { task.ContinueWith(t => TaskCompleted(task, dtStart), this.Scheduler); } return task; }
当执行一个任务或子任务,无论是成功、失败还是用户取消,都会执行一个方法:TaskCompleted 或 TaskCompletedResult。这些方法会执行存储在属性中的回调方法,这些属性由使用该库的类设置。
存储了开始和结束时间,以及任务或子任务的每个项的时间。控制这些时间很困难,因为进程是异步的。
进度由三种方法控制:配置任务、开始报告任务或子任务的进度项,以及报告任务或子任务项进度的结束;这些方法又会触发回调方法来通知变化。
要定义回调方法,应执行以下方法:
- SetMethodsCallback
- SetSubTaskMethodsCallback
类 TaskProgressViewModel
控制任务的执行并提供执行进度通知的支持。该类启动具有业务规则的方法并发送进度。对于可视化部分,在项目中创建了控件和 Windows 窗体:Asimatica.FW.AsynTaskWin。项目中的 WPF 窗体:Asimatica.FW.AsynTaskWpf 是初始原型,但不完整。
任务进度项目
TaskProgressWindow 控件和 frmTaskProgressWindow 窗体。
TaskProgressWindow 控件以可视化方式呈现进度数据。
客户应用程序
客户窗口
项目: Asimatica.FW.AsynTask.WinTest,有五个任务,它们可以同时执行。
数据模型
文件:ProcessModel.cs 包含两个模型和一个模拟类来生成测试数据。
具有业务规则的服务
Task Services.cs 文件包含具有业务规则的类和方法,方法必须具有接口 ITaskManagement 的属性之一的签名:DoTaskAsync、DoTaskWithouParameterAsync、DoTaskResultAsync、DoTaskResultWithouParameterAsync。
ViewModel
类:MainTestViewModel,定义了主窗体的 ViewModel。该类包含数据模型、业务规则任务(服务)和 TaskProgressViewModel 对象,用于管理执行和进度。
frmMain 窗体
该窗体执行五个由服务定义的任务。
-
测试 1:打开 frmTaskProgressWindow 窗体来执行任务。
-
测试 2:打开另一个 frmTaskProgressWindow 窗体来执行任务。
-
测试 3:将进度控件集成到窗体中。
-
测试 4:任务在不使用视觉组件的情况下执行。
-
测试 5:任务不使用内置视觉组件;它在客户端窗体中使用进度条来可视化地提交进度。
客户 WPF
项目:Asimatica.FW.AsynTask.WpfTest,是初始原型,但不完整。
兴趣点
-
使用 TAP 模式异步运行长时间运行的任务。
- 向用户显示进度指示器和数据,如每个项目的开始时间和总时间。使用窗体或将进度控件添加到窗体中以显示进度。
链接
文档:基于任务的异步模式 (TAP)
http://www.microsoft.com/en-us/download/details.aspx?id=19957
Task Parallel Library
https://codeproject.org.cn/Articles/152765/Task-Parallel-Library-of-n
WinForms 和 TPL - 实现快速多任务和响应式用户界面
https://codeproject.org.cn/Articles/748815/WinForms-and-TPL-Achieving-quick-Multitasking-and
BackgroundWorker - VS 2005 应用程序,附带 WinForms 示例
https://codeproject.org.cn/Articles/42103/Generic-Background-Worker
工具
http://wftoolkit.codeplex.com/
http://mvvmlight.codeplex.com/
http://MVVMhelpers.codeplex.com/
历史记录
版本 1.0.0。