简体   繁体   English

如何使函数异步运行

[英]How to make a function run async

I was reading about async-await programming and I am confused in a scenario where I want to make a function run asynchronously. 我正在阅读有关异步等待编程的信息,在要使函数异步运行的情况下,我感到困惑。 For example I want to display an Image on my UI. 例如,我想在UI上显示图像。 So, on the UI thread I call a function which would fetch the image from storage and apply the image onto the UI. 因此,在UI线程上,我调用了一个函数,该函数将从存储中获取图像并将图像应用于UI。

What is the correct way to do this? 正确的方法是什么?

METHOD 1 方法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;
            });
        }
    }
}

METHOD 2 方法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;
    }
}

As reading a file from disk is mostly about asynchronous IO, you can take advantage of the wide range of asynchronous API provided by the Windows Phone platform. 由于从磁盘读取文件主要与异步IO有关,因此您可以利用Windows Phone平台提供的各种异步API。

There is no need to use Task.Factory.StartNew or Task.Run , meaning there is no need for an extra ThreadPool thread at all. 不需要使用Task.Factory.StartNewTask.Run ,这意味着根本不需要额外的ThreadPool线程。 Currently, your code isn't truly asynchronous, and note that async void is ment only for top level event handlers and shouldn't be used otherwise. 当前,您的代码并不是真正异步的,请注意, async void仅适用于顶级事件处理程序,否则不应使用。

You can take advantage of the async API as follows: 您可以使用异步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;
}

Something like this: 像这样:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM