如何使函数运行异步

时间:2014-11-22 20:29:03

标签: c# .net asynchronous windows-phone async-await

我正在阅读有关async-await编程的内容,我感到很困惑,我想让一个函数异步运行。例如,我想在我的UI上显示一个图像。因此,在UI线程上,我调用了一个函数,该函数将从存储中获取图像并将图像应用到UI上。

这样做的正确方法是什么?

方法1

private async void SetImage()
{
    await Task.Run(() =>
    {
        byte[] fullViewImageBytes = Utils.GetImageFromStorage(fileName);

        if (fullViewImageBytes != null)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                MemoryStream memStream = new MemoryStream(fullViewImageBytes);
                BitmapImage image = new BitmapImage();
                image.SetSource(memStream);
                userImage.Source = image;
            });
        }
    }
}

方法2

private async void SetImage()
{
    await Task.Delay(1);

    byte[] fullViewImageBytes = Utils.GetImageFromStorage(fileName);

    if (fullViewImageBytes != null)
    {
         MemoryStream memStream = new MemoryStream(fullViewImageBytes);
         BitmapImage image = new BitmapImage();
         image.SetSource(memStream);
         userImage.Source = image;
    }
}

2 个答案:

答案 0 :(得分:4)

从磁盘读取文件主要是关于异步IO,您可以利用Windows Phone平台提供的各种异步API。

无需使用Task.Factory.StartNewTask.Run,这意味着根本不需要额外的ThreadPool线程。目前,您的代码并非真正异步,请注意async void仅适用于顶级事件处理程序,否则不应使用。

您可以按如下方式利用异步API:

public async Task<BitmapImage> CreateImageFromFileAsync(string imagePath)
{
    StorageFile storageFile = await StorageFile.GetFileFromPathAsync(imagePath);
    IRandomAccessStream imageFileStream = await storageFile.OpenReadAsync();

    BitmapImage image = new BitmapImage();
    await image.SetSourceAsync(imageFileStream);

    return image;
}

答案 1 :(得分:0)

这样的事情:

private static async Task<BitmapImage> GetImageFromStorageAsync(string fileName)
{
    var bytes = await Task.Factory
                 .StartNew((f)=>Utils.GetImageFromStorage((string)f), fileName)
                 .ConfigureAwait(false);
    MemoryStream memStream = new MemoryStream(bytes);
    BitmapImage image = new BitmapImage();
    image.SetSource(memStream);
    return image;
}

private async Task SetImage()
{
    var image = await GetImageFromStorageAsync(fileName);
    userImage.Source = image;
}