查找并行异步任务的结果

时间:2015-11-20 15:21:48

标签: c# asp.net .net async-await

基于this question我正在尝试设置代码以将多个图像并行保存到Azure Blob存储。下面这个方法工作正常,等待Task.WhenAll(任务)等待所有人完成,然后再继续。

唯一的麻烦是,我希望能够找出每个在我们的数据库中存储信息的请求是否真的成功了。 _db.AddImageAsync返回一个bool,下面的代码等待所有任务完成,但是当我检查所有任务的结果时,每个都是假的(即使我在括号内实际返回true)。

Enumerable中的每个任务都表示,即使我逐步执行了断点并且每个任务都已执行,结果仍未计算。

  var tasks = wantedSizes.Select(async (wantedSize, index) =>
  {
    var resize = size.CalculateResize(wantedSize.GetMaxSize());
    var quality = wantedSize.GetQuality();

    using (var output = ImageProcessHelper.Process(streams[index], resize, quality))
    {
        var path = await AzureBlobHelper.SaveFileAsync(output, FileType.Image);
        var result = await _db.AddImageAsync(id, wantedSize, imageNumber, path);
        return result;
    }
  });

  await Task.WhenAll(tasks)

  if (!tasks.All(task => task.Result))
      return new ApiResponse(ResponseStatus.Fail);

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:6)

由于.Select(是惰性求值并返回IEnumerable<Task<bool>>,因此当您多次迭代结果时,会导致.Select(多次运行。在其上加.ToList()使其成为List<Task<bool>>,并且只执行.Select(一次,多个枚举将在返回的List<Task<bool>>之上,这将不会产生副作用

  var tasks = wantedSizes.Select(async (wantedSize, index) =>
  {
    var resize = size.CalculateResize(wantedSize.GetMaxSize());
    var quality = wantedSize.GetQuality();

    using (var output = ImageProcessHelper.Process(streams[index], resize, quality))
    {
        var path = await AzureBlobHelper.SaveFileAsync(output, FileType.Image);
        //Double check your documentation, is _db.AddImageAsync thread safe?
        var result = await _db.AddImageAsync(id, wantedSize, imageNumber, path);
        return result;
    }
  }).ToList(); //We run the Select once here to process the .ToList().

  await Task.WhenAll(tasks) //This is the first enumeration of the variable "tasks".

  if (!tasks.All(task => task.Result)) //This is a 2nd enumeration of the variable.
      return new ApiResponse(ResponseStatus.Fail);