如何使用Async/Await进行进度报告

32
假设我有一个文件列表,我需要使用C#项目中的FTP相关类将它们复制到Web服务器。在此,我想使用Async/Await功能,并且希望同时显示多个进度条以进行多个文件上传。每个进度条表示每个文件上传状态。请指导我如何做到这一点。
当我们使用后台工作器来完成这种工作时,非常容易,因为后台工作者具有进度更改事件。那么如何使用Async/Await处理这种情况呢?如果可能的话,请给我提供示例代码。谢谢

4
http://blogs.msdn.com/b/dotnet/archive/2012/06/06/async-in-4-5-enabling-progress-and-cancellation-in-async-apis.aspx - vittore
1
http://simplygenius.net/Article/AncillaryAsyncProgress - Thomas
基于任务的异步模式解释了如何实现此功能。 - Stephen Cleary
1个回答

39

这是一篇有关于异步API中进展和取消的文章,以下是其中的示例代码:

public async Task<int> UploadPicturesAsync(List<Image> imageList, 
     IProgress<int> progress)
{
      int totalCount = imageList.Count;
      int processCount = await Task.Run<int>(() =>
      {
          int tempCount = 0;
          foreach (var image in imageList)
          {
              //await the processing and uploading logic here
              int processed = await UploadAndProcessAsync(image);
              if (progress != null)
              {
                  progress.Report((tempCount * 100 / totalCount));
              }
              tempCount++;
          }
          return tempCount;
      });
      return processCount;
}

private async void Start_Button_Click(object sender, RoutedEventArgs e)
{
    int uploads=await UploadPicturesAsync(GenerateTestImages(),
        new Progress<int>(percent => progressBar1.Value = percent));
}

如果您希望对每个文件分别进行报告,则需要为IProgress使用不同的基本类型:

public Task UploadPicturesAsync(List<Image> imageList, 
     IProgress<int[]> progress)
{
      int totalCount = imageList.Count;
      var progressCount = Enumerable.Repeat(0, totalCount).ToArray(); 
      return Task.WhenAll( imageList.map( (image, index) =>                   
        UploadAndProcessAsync(image, (percent) => { 
          progressCount[index] = percent;
          progress?.Report(progressCount);  
        });              
      ));
}

private async void Start_Button_Click(object sender, RoutedEventArgs e)
{
    int uploads=await UploadPicturesAsync(GenerateTestImages(),
        new Progress<int[]>(percents => ... do something ...));
}

你的代码没问题,但是我该如何展示多个进度条来显示多个文件上传的状态呢?需要指导。谢谢。 - Thomas
1
@Thomas,你的UploadAndProcessAsync本身应该遵循相同的模式,并具有“IProgress<T> progress”参数。 - vittore
4
如果您能抽出宝贵的时间来完成代码,那将非常有帮助。假设imageList有3个文件名,我想为它们显示三个进度条。请指导我如何添加3个进度条,并从UploadPicturesAsync()函数更新这些进度条的状态。我不知道IProgress是什么以及它是如何工作的。谢谢。 - Thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接