部分完成,使用多个Task<T>还是IProgress<T>?

4
我正在使用一个异步操作,需要3个步骤才能完成,并在完成之前返回部分结果。原来它使用事件来标识进度,我想将其适当地封装为可等待的操作(或一系列操作)。
确切地说,这是Windows Phone 7中的PhotoCamera.CaptureImage方法,按以下顺序触发事件(带有相关结果类型):
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)

这感觉不太干净,任务和回调混合在一起。我知道有 IProgress<T>。然而,进度值不是统一类型的 (Stream, Stream, bool)……那不会把 IProgress<T> 模式拉得太长了吗?
使用多个按顺序等待的 Task<T> 是一个选项,但这意味着我也必须以某种方式强制执行特定的顺序。也许每个任务结果都可以包含“下一个”任务作为成员:
ThumbnailResult thumbnailResult = await photoCamera.CaptureImageAsync();
...
ImageResult imageResult = await thumbnailResult.NextTask;
...
bool finalResult = await imageResult.NextTask;

我仍然认为这里离正确答案还有些距离。有什么想法吗?

1个回答

2

个人建议创建一个类,其中包含3个方法,返回Task<T>。调用者可以按任意顺序调用这3个方法,而程序总是正常工作的。如果先调用GetFinalResultAsync,然后再调用GetThumbnailAsync,那么唯一的后果就是在使用await时,第二个Task<T>将已经有了结果并且会同步返回。

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);

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