多任务或IProgress部分完成?

发布于 2024-12-19 07:15:01 字数 1334 浏览 3 评论 0原文

我正在使用分三步完成的异步操作,在完成之前返回部分结果。最初,它使用事件来表示进度,我想将其正确包装为可等待操作(或一系列操作)。

确切地说,它是 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。但是,进度值不是统一类型(Stream、Stream、bool)...这是否会将 IProgress 模式拉伸得太远?

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

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

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

I am using an asynchronous operation that completes in three steps, returning partial results before completion. Originally it's using events to signal progress, and I want to wrap it properly as an awaitable operation (or a chain of them).

To be exact, it's the PhotoCamera.CaptureImage method in Windows Phone 7, which fires events in the following order (with relevant result types):

  1. CaptureStarted, not that interesting to me
  2. CaptureThumbnailAvailable (Stream)
  3. CaptureImageAvailable (Stream)
  4. CaptureCompleted (bool)

How to wrap this? Currently I'm using a TaskCompletionSource and calling SetResult on CaptureCompleted. It does not address steps 2 and 3, the thumbnail and image becoming available. I decided to use callbacks for those instead.

My extension method (leaving out the code for brevity):

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

This doesn't feel entirely clean, a mixture of Tasks and callbacks. I know of IProgress<T>. However, the progress values aren't of uniform type (Stream, Stream, bool)... and wouldn't that stretch the IProgress<T> pattern too far?

Using multiple Task<T> that are awaited in order is an option, but that supposes a specific order that I'd also have to enforce somehow. Maybe each task result could contain the "next" task as a member:

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

I still think that I'm somewhat off the mark here. Ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

听风念你 2024-12-26 07:15:01

就我个人而言,我将为其创建一个类,其中包含 3 个返回 Task 的方法。调用者可以按照他想要的任何顺序调用这 3 个方法,并且它始终有效。如果先调用 GetFinalResultAsync,然后调用 GetThumbnailAsync,则唯一的结果是,当使用 await 时,第二个 Task 将获得结果,并且它会同步返回。

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

Personally i'll create a class for it with 3 methods returning Task<T>. The caller will be able to call the 3 methods in any order he wants and it'll always work. if GetFinalResultAsync is called first and then GetThumbnailAsync then only consequence is that the second Task<T> will aready have a result when await is used and it will return synchronously.

var photoCapture = photoCamera.BeginCapture();

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

To wait for everything :

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文