使用IProgress实现异步编程的进程通知

2/11/2016来源:C#应用人气:1338

 

在异步编程中,有时候希望把进度展示出来,借助iprogress<in T>可以实现。

 

IPRogress<in T>只提供了一个方法void Report(T value),通过Report方法把一个T类型的值报告给IProgress,然后IProgress<in T>的实现类Progress<in T>的构造函数接收类型为Action<T>的形参,通过这个委托让进度显示在UI界面中

 

首先写一个方法,使用Report方法报告进度。

 

        public void DoProcessing(IProgress<int> progress)
        {
            for (int i = 0; i != 100; ++i)
            {
                Thread.Sleep(100);
                if (progress != null)
                {
                    progress.Report(i);
                }
            }
        }

 

如何让这个进度显示到UI界面中呢?

 

实现IProgress<in T>接口的Progress<int T>类,接收一个Action<T>,通过这个委托让进度显示到UI界面中。

 

        private async void button1_Click(object sender, EventArgs e)
        {
            //当前线程
            var progress = new Progress<int>(percent => { label1.Text = percent + "%"; });
            //线程池线程
            await Task.Run(() => DoProcessing(progress));
            label1.Text = "结束";
        }

 

又比如,当需要异步读取一个远程文件。

 

public async Task DownloadFileAsync(string fileName, IProgress<int> progress)
{
    using(var fileStream...)
    {
        using(var ftpStream = ...)
        {    
            while(true)
            {
                //异步读取数据
                var bytesRead = await ftpStream.ReadAsync(...);
                if(bytesRead == 0)
                {
                    return;
                }
                //异步写数据
                await fileStream.WriteAsync(...);
                if(progress != null)
                {
                    progress.Report(bytesRead);
                }
            }
        }
    }
}