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):
CaptureStarted, not that interesting to meCaptureThumbnailAvailable(Stream)CaptureImageAvailable(Stream)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?
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. ifGetFinalResultAsyncis called first and thenGetThumbnailAsyncthen only consequence is that the secondTask<T>will aready have a result when await is used and it will return synchronously.To wait for everything :