Multiple tasks <T> or IProgress <T> for partial completion?

I use an asynchronous operation that completes in three steps, returning partial results to completion. It initially uses events to track progress, and I want to correctly wrap it as an await operation (or a chain of them).

More precisely, this is the PhotoCamera.CaptureImage method in Windows Phone 7, which fires events in the following order (with the corresponding result types):

  • CaptureStarted , not that interesting to me
  • CaptureThumbnailAvailable (stream)
  • CaptureImageAvailable (stream)
  • CaptureCompleted (bool)

How to wrap it? I am currently using TaskCompletionSource and SetResult on CaptureCompleted . It does not affect steps 2 and 3, thumbnail and image become available. I decided to use callbacks for them.

My extension method (for brevity, let's leave the code):

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

It does not seem completely clean, it is a mixture of tasks and callbacks. I know IProgress<T> . However, the progress values ​​do not have the same type (Stream, Stream, bool) ... and is the IProgress<T> template too stretched?

Using multiple Task<T> , expected in order, is an option, but it involves a certain order, which I will also need to somehow provide. Perhaps each result of the task may contain the following task as a member:

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

I still think I'm a little from here. Ideas?

+4
source share
1 answer

Personally, I will create a class for it with 3 methods that return Task<T> . The caller will be able to call 3 methods in any order, and it will always work. if GetFinalResultAsync is called first, and then GetThumbnailAsync , then only the consequence is that the second Task<T> will 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(); 

Waiting 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); 
+2
source

Source: https://habr.com/ru/post/1384406/


All Articles