解包异步操作,它是TaskCompletionSource中的异步回调

时间:2015-10-17 20:06:20

标签: c# xamarin.ios async-await task-parallel-library taskcompletionsource

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

为了使我的方法等待,我将方法包装在TaskCompletionSource中。问题是在API回调中,我需要调用另一个必须返回Task的方法。完成源将其结果设置为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>

我应该如何展开嵌套的任务,以便我只返回public Color MakeTransparent(Color c, int threshold) { // calculate the weighed brightness: byte val = (byte)((c.R * 0.299f + c.G * 0.587f + c.B * 0.114f)); return val < threshold ? Color.FromArgb(0, c.R, c.G, c.B) : c; }

1 个答案:

答案 0 :(得分:3)

您不需要使用TaskCompletionSource<Task<IBitmap>>,请使用TaskCompletionSource<UIImage>返回完成后返回图像的任务。等待该任务异步获取结果,然后您可以使用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
}