推荐一种异步线程执行过程中更新进度的方法


在实际应用中,对于耗时较长或者耗费性能的操作,为了避免UI卡顿,通常采用后台异步线程的方式进行处理,但用户需要知道当前操作的执行进度(如当前进度百分比),以及一些更详细的过程信息(如共分5步,当前是正在执行第几步)等内容。实现此功能有很多种方法,今天介绍一种通过.NET自带的IProgress接口实现进度上报的操作方法,谨供学习分享使用,如有不足之处,还请指正。

 

IProgress概述

 

IProgress接口是微软在.NET Framework4.5及之后的版本中提供的一种用于异步方法中进度上报的方法接口及实现。IProgress<T>及它的实现类Progress<T>是泛型实现,它接收基础数据类型或自定义的引用类型。Progress<T>初始化对象时,接收一个Action<T> 的handler,当调用接口的Report(T value)方法时,就会执行Action<T>对应的handler委托方法进行更新进度。

涉及知识点如下:

  1. Report<T value> 用于向外报告一个进度更新。
  2. Progress(Action<T> handler) 实现类的构造函数,参数为更新进度的委托。

 

示例代码

 

在本示例中,创建Execute方法,模拟后台耗时较长的任务,并在执行过程中通过IProgress接口的Report方法上报执行进度。如下所示:

private async Task Execute(IProgress<TaskReport> progress)
{
	for (int i = 0; i < 100; i++)
	{
		//do somthing
		await Task.Delay(200);
		progress.Report(new TaskReport()
		{
			Percent=i,
			Msg=$"当前是第{i}个步骤,进行中"
		});
	}
	progress.Report(new TaskReport()
	{
		Percent=100,
		Msg="完成"
	});
}

接着创建IProgress的实例对象,并传入当Report方法调用时,需要执行的委托RefreshUI,用于刷新页面的进度,如下所示:

private async void btnExceute_Click(object sender, EventArgs e)
{
	IProgress<TaskReport> progress = new Progress<TaskReport>(RefreshUI);
	await Execute(progress);
}

其中RefreshUI方法,主要用于为UI页面上的进度条和Label赋值,如下所示:

private void RefreshUI(TaskReport taskReport)
{
	this.pb1.Value = taskReport.Percent;
	this.lblMsg.Text = taskReport.Msg;
}

 

演示效果

 

运行实例,点击执行按钮如下所示:

以上就是《推荐一种异步线程执行过程中更新进度的方法》的全部内容,旨在抛砖引玉,一起学习,共同进步!