多个Task< T>或IProgress< T>部分完成

本文关键字:Task 多个 IProgress | 更新日期: 2023-09-27 18:16:26

我使用的是一个分三步完成的异步操作,在完成之前返回部分结果。最初它使用事件来表示进度,我想把它包装成一个await可操作(或它们的链)。

确切地说,它是照相机。方法,它按以下顺序触发事件(带有相关的结果类型):

  1. CaptureStarted,对我来说不是那么有趣
  2. CaptureThumbnailAvailable (Stream)
  3. CaptureImageAvailable (Stream)
  4. CaptureCompleted (bool)

如何包装?目前我正在使用TaskCompletionSource并在CaptureCompleted上调用SetResult。它没有地址步骤2和3,缩略图和图像变得可用。我决定用回调来代替。

我的扩展方法(为了简洁,省略了代码):

public static Task<bool> CaptureImageAsync(this PhotoCamera photoCamera,
                                           Action<Stream> thumbnailAvailableCallback,
                                           Action<Stream> imageAvailableCallback)

这感觉不太干净,是task和回调的混合体。我知道IProgress<T>。然而,进度值不是统一的类型(Stream, Stream, bool)…这难道不会把IProgress<T>模式延伸得太远吗?

使用顺序等待的多个Task<T>是一种选择,但这假设了一个特定的顺序,我也必须以某种方式强制执行。也许每个任务结果都可以包含"下一个"任务作为成员:

ThumbnailResult thumbnailResult = await photoCamera.CaptureImageAsync();
...
ImageResult imageResult = await thumbnailResult.NextTask;
...
bool finalResult = await imageResult.NextTask;

我仍然认为我在这一点上有点偏离主题。想法吗?

多个Task< T>或IProgress< T>部分完成

我个人将创建一个类,它有3个方法返回Task<T>。调用者将能够以他想要的任何顺序调用这3个方法,并且它总是有效的。如果首先调用GetFinalResultAsync,然后调用GetThumbnailAsync,那么唯一的结果是第二个Task<T>在使用await时已经有结果,并且它将同步返回。

var photoCapture = photoCamera.BeginCapture();
var thumbnailResult = await photoCapture.GetThumbnailAsync();
var imageResult = await photoCapture.GetImageAsync();
var finalResult = await photoCapture.GetFinalResultAsync();

等待一切:

var thumbnailTask = photoCapture.GetThumbnailAsync();
var imageTask = photoCapture.GetImageAsync();
var finalTask = photoCapture.GetFinalResultAsync();
await Task.WhenAll(thumbnailTask, imageTask, finalTask);
DoWork(thumbnailTask.Result, imageTask.Result, finalTask.Result);