2

我的服务中有一个方法被我的视图模型调用以获取图像。该图像是从使用回调机制而不是等待的外部库(Xamarin 中的 iOS API)中获取的。

为了使我的方法可以等待,我将方法包装在 TaskCompletionSource 中。虽然问题出在 API 回调中,但我需要调用另一个必须返回任务的方法。完成源将它的结果设置为Task<IBitmap>,然后我返回 CompletionSource 任务,它现在变成Task<Task<IBitmap>>了 所以我最终得到的结果是我的最终返回值Task<Task<IBitmap>>而不是Task<Bitmap>.

public Task<IBitmap> GetAlbumCoverImage(IAlbum album)
{
    var assets = PHAsset.FetchAssetsUsingLocalIdentifiers(new string[] { album.Identifier }, null);

    var asset = assets.FirstOrDefault(item => item is PHAsset);
    if(asset == null)
    {
        return null;
    }

    var taskCompletionSource = new TaskCompletionSource<Task<IBitmap>>();
    PHImageManager.DefaultManager.RequestImageForAsset(
        asset, 
        new CoreGraphics.CGSize(512, 512), 
        PHImageContentMode.AspectFit, 
        null, 
        (image, info) => taskCompletionSource.SetResult(this.ConvertUIImageToBitmap(image)));

    return taskCompletionSource.Task;
}

private Task<IBitmap> ConvertUIImageToBitmap(UIImage image)
{
    var imageData = image.AsJPEG().GetBase64EncodedData(Foundation.NSDataBase64EncodingOptions.SixtyFourCharacterLineLength);
    byte[] imageBytes = new byte[imageData.Count()];

    System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, imageBytes, 0, Convert.ToInt32(imageData.Count()));

    return BitmapLoader.Current.Load(new MemoryStream(imageBytes), 512, 512);
}

我应该如何解开嵌套的任务,以便我只返回一个Task<IBitmap>

4

1 回答 1

4

您不需要使用TaskCompletionSource<Task<IBitmap>>, 使用TaskCompletionSource<UIImage>which 返回任务,完成后返回图像。等待该任务异步获取结果,然后您可以使用以下命令进行转换ConvertUIImageToBitmap

public async Task<IBitmap> GetAlbumCoverImage(IAlbum album)
{
    // ...
    var taskCompletionSource = new TaskCompletionSource<UIImage>(); // create the completion source
    PHImageManager.DefaultManager.RequestImageForAsset(
        asset, 
        new CoreGraphics.CGSize(512, 512), 
        PHImageContentMode.AspectFit, 
        null, 
        (image, info) => taskCompletionSource.SetResult(image)); // set its result

    UIImage image = await taskCompletionSource.Task; // asynchronously wait for the result
    return await ConvertUIImageToBitmap(image); // convert it
}
于 2015-10-17T20:10:54.313 回答