Несколько задач <T>или IProgress <T>для частичного завершения? - PullRequest
4 голосов
/ 03 декабря 2011

Я использую асинхронную операцию, которая завершается в три этапа, возвращая частичные результаты до завершения.Первоначально он использует события для оповещения о прогрессе, и я хочу правильно обернуть его как await способную операцию (или их цепочку).

Точнее, это метод PhotoCamera.CaptureImage в Windows Phone 7, который генерирует события в следующем порядке (с соответствующими типами результатов):

  1. CaptureStarted, не очень интересно для меня
  2. CaptureThumbnailAvailable (Stream)
  3. CaptureImageAvailable (Stream)
  4. CaptureCompleted (bool)

Как это обернуть?В настоящее время я использую TaskCompletionSource и звоню SetResult на CaptureCompleted.Он не обращается к шагам 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 голосов
/ 03 декабря 2011

Лично я создам для него класс с 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);
...