小小一方士 C# Async\Await 之 上传/下载文件进度条实现原理

关于上传下载文件(图片等),涉及到UI进度条的显示,c#中 System.IProgress提供了相应的api.

namespace System
{
    //
    // 摘要:
    //     定义进度更新的提供程序。
    //
    // 类型参数:
    //   T:
    //     进度更新值的类型。此类型参数是逆变。即可以使用指定的类型或派生程度更低的类型。有关协变和逆变的详细信息,请参阅 泛型中的协变和逆变。
    public interface IProgress<in T>
    {
        //
        // 摘要:
        //     报告进度更新。
        //
        // 参数:
        //   value:
        //     进度更新之后的值。
        void Report(T value);
    }
}

对于多个文件的使用,这个使用还是很不错的选择,如下为相关使用代码:

 1   async Task<int> UploadPicturesAsync(List<object> imageList, IProgress<int> progress, CancellationToken ct)
 2         {
 3             try
 4             {
 5                 int totalCount = imageList.Count;
 6                 int processCount = await Task.Run<int>(() =>
 7                 {
 8                     int tempCount = 0;
 9                     foreach (var image in imageList)
10                     {
11                         //await the processing and uploading logic here
12                         //int processed = await UploadAndProcessAsync(image);
13                         // 异步上传/下载方法
14                         bool success = Task.Run(async () =>
15                                   {
16                                       await Task.Delay(2000);
17                                       return image.ToString() == "取消" ? false : true;
18                                   }).Result;
19                         if (ct.IsCancellationRequested)     //判断是否取消
20                         {
21                             ct.ThrowIfCancellationRequested();
22                         }  
23                         if (progress != null)
24                         {
25                             progress.Report((tempCount * 100 / totalCount));
26                         }
27                         tempCount++;
28                     }
29 
30                     return tempCount;
31                 });
32                 return processCount;
33             }
34             catch (OperationCanceledException ex)
35             {    
36                 throw ex;
37             }
38         }
39         // 向应该被取消的 System.Threading.CancellationToken 发送信号
40         // cts.Token 传播有关应取消操作的通知。
41         CancellationTokenSource cts = new CancellationTokenSource();
42         /// <summary>
43         /// 进度条 异步上传   异步上传button
44         /// </summary>
45         public async void ProgressBar()
46         {
47             //construct Progress<T>, passing ReportProgress as the Action<T> 
48             //Progress 提供调用每个报告进度的值的回调的 
49             var progressIndicator = new Progress<int>(ReportProgress);
50             //call async method
51             // 模拟上传/下载文件
52             List<object> files = new List<object>
53             {
54                 1,2,"取消",3,4,5,2,4,11
55             };
56             try
57             {
58                 int uploads = await UploadPicturesAsync(files, progressIndicator, cts.Token);
59                 Console.WriteLine($"upload Count=>{uploads}");
60             }
61             catch (OperationCanceledException ex)
62             {
63                 Console.WriteLine($"上传已取消:{ex.Message}");
64             }
65         }
66         /// <summary>
67         /// UI线程交互
68         /// </summary>
69         /// <param name="value"></param>
70         void ReportProgress(int value)
71         {
72             //UI 线程显示进度信息
73             Console.WriteLine($"{value}%");
74             if (value == 33)   //模拟 取消按钮处理
75             {
76                 cts.Cancel();
77             }
78             //Update the UI to reflect the progress value that is passed back.
79         }

 参考:https://devblogs.microsoft.com/dotnet/async-in-4-5-enabling-progress-and-cancellation-in-async-apis/

posted @ 2019-06-27 11:59  L-Harrison  阅读(1045)  评论(0编辑  收藏  举报