C#在同步上下文中运行异步任务

希望

我在C#异步方面没有太多经验。

任务-从Internet加载位图。以前,我只是按1个1个同步地加载它们。异步加载它们可以更快地得到结果。在下面,我举了两个例子,我如何获得单个图像-GetImageGetImageAsync对于图像列表,我将使用LoadImagesLoadImages2

LoadImages将在异步中运行同步功能(全部同时(?)),LoadImages2将在异步中运行异步功能并产生相同的结果(?)。我不完全了解的东西-in GetImageAsync await request.GetResponseAsync()我真的需要吗?这是做同一件事的一种“更好”的方式吗?LoadImages之间真的有任何区别吗LoadImages2

目前,我正在考虑选择GetImageLoadImages选择。另外,我不想用来装饰每个函数async Task,我只需要异步加载这些图像即可。

public Bitmap GetImage(string url)
{
    HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
    using (WebResponse response = request.GetResponse())
    using (Stream responseStream = response.GetResponseStream())
        return new Bitmap(responseStream);
}

public async Task<Bitmap> GetImageAsync(string url)
{
    HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
    using (WebResponse response = await request.GetResponseAsync())
    using (Stream responseStream = response.GetResponseStream())
        return new Bitmap(responseStream);
}

private Dictionary<string, Bitmap> LoadImages(List<string> urls)
{
    Dictionary<string, Bitmap> images = new Dictionary<string, Bitmap>();
    Task.WaitAll(urls.Select(url => 
        Task.Run(() =>
        {
            images.Add(url, GetImage(url));
        })).ToArray());
    return images;
}

private Dictionary<string, Bitmap> LoadImages2(List<string> urls)
{
    Dictionary<string, Bitmap> images = new Dictionary<string, Bitmap>();
    Task.WhenAll(urls.Select(url =>
        Task.Run(async () =>
        {
            images.Add(url, await GetImageAsync(url));
        })));
    return images;
}
斯蒂芬·克莱里

这里的术语和技术选择有些混乱。

以前,我只是按1个1个同步地加载它们。异步加载它们可以更快地得到结果。

您的意思是串行并发,而不是同步异步串行是一次一次,而并发是一次多个事情。同步代码可以是串行或并发的,异步代码可以是串行或并发的。

其次,并发并行Task.Run是并行的一种形式,这是一种通过向问题中添加线程来实现并发的方法。异步是一种通过释放线程来实现并发的方法

LoadImages是在同步代码中使用并行性的示例。这种方法的优点是它使顶级方法保持同步,因此无需更改任何调用代码。缺点是,这在资源使用方面很浪费,并且与下面发生的事情没有很好的概念契合(I / O绑定代码更自然地由异步API表示)。

LoadImages2是并行和异步代码的混合,这有点令人困惑。没有线程(即),异步并发更容易表示Task.Run返回值而不是将集合更新作为副作用也更自然。因此,如下所示:

private async Task<Dictionary<string, Bitmap>> LoadImagesAsync(List<string> urls)
{
  Bitmap[] result = await Task.WhenAll(urls.Select(url => GetImageAsync(url)));

  return Enumerable.Range(0, urls.Length).ToDictionary(i => urls[i], i => result[i]);
}

PS:如果您决定使用(同步)LoadImages,则需要修复一个争用条件,其中各种并行线程将全部尝试更新字典而不锁定它。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C#等待的任务停留在相同的上下文中

来自分类Dev

C#异步/等待:创建任务后保留AsyncLocal <T>上下文

来自分类Dev

异步和同步上下文

来自分类Dev

异步和同步上下文

来自分类Dev

传递给 Task.WaitAll() 的任务会在不同的上下文中运行吗?

来自分类Dev

如何在数据库上下文中运行没有C#返回值的存储过程?

来自分类Dev

在多个上下文中保持NSManagedObjects同步

来自分类Dev

在Dispatcher.Main的上下文中执行网络任务

来自分类Dev

cron任务是在什么上下文中执行的?

来自分类Dev

上下文中的任务和多项操作

来自分类Dev

同步上下文未保留异步/等待?

来自分类Dev

同步上下文未保留异步/等待?

来自分类Dev

如何在Meteor上下文中运行脚本?

来自分类Dev

在全局上下文中运行的Javascript绑定函数

来自分类Dev

在C#中不安全代码的上下文中什么是不受信任的程序集

来自分类Dev

如何在C#上下文中引用包含单引号的F#名称?

来自分类Dev

在EF数据库上下文中两次使用相同的c#模型

来自分类Dev

CS0103 C#当前上下文中不存在名称“ Json”

来自分类Dev

C#错误CS0103当前上下文中不存在名称“ originalImage”

来自分类Dev

在C#中的程序集上下文中,激活作用域指的是什么?

来自分类Dev

在C#泛型类型的上下文中,什么是类型标识?

来自分类Dev

C#关键字“ this”在当前上下文中不可用

来自分类Dev

“名称“ DisplayAlert”在当前上下文中不存在。” Xamarin C#

来自分类Dev

在F#上下文中了解此关键字的C#

来自分类Dev

事件,在C#中的操作-在线程上下文中

来自分类Dev

如何在C#上下文中引用包含单引号的F#名称?

来自分类Dev

在C#中的动态上下文中使用关键字

来自分类Dev

关键字,这在C#的当前上下文中不可用

来自分类Dev

名称“ Log”在当前上下文中不存在c#

Related 相关文章

  1. 1

    C#等待的任务停留在相同的上下文中

  2. 2

    C#异步/等待:创建任务后保留AsyncLocal <T>上下文

  3. 3

    异步和同步上下文

  4. 4

    异步和同步上下文

  5. 5

    传递给 Task.WaitAll() 的任务会在不同的上下文中运行吗?

  6. 6

    如何在数据库上下文中运行没有C#返回值的存储过程?

  7. 7

    在多个上下文中保持NSManagedObjects同步

  8. 8

    在Dispatcher.Main的上下文中执行网络任务

  9. 9

    cron任务是在什么上下文中执行的?

  10. 10

    上下文中的任务和多项操作

  11. 11

    同步上下文未保留异步/等待?

  12. 12

    同步上下文未保留异步/等待?

  13. 13

    如何在Meteor上下文中运行脚本?

  14. 14

    在全局上下文中运行的Javascript绑定函数

  15. 15

    在C#中不安全代码的上下文中什么是不受信任的程序集

  16. 16

    如何在C#上下文中引用包含单引号的F#名称?

  17. 17

    在EF数据库上下文中两次使用相同的c#模型

  18. 18

    CS0103 C#当前上下文中不存在名称“ Json”

  19. 19

    C#错误CS0103当前上下文中不存在名称“ originalImage”

  20. 20

    在C#中的程序集上下文中,激活作用域指的是什么?

  21. 21

    在C#泛型类型的上下文中,什么是类型标识?

  22. 22

    C#关键字“ this”在当前上下文中不可用

  23. 23

    “名称“ DisplayAlert”在当前上下文中不存在。” Xamarin C#

  24. 24

    在F#上下文中了解此关键字的C#

  25. 25

    事件,在C#中的操作-在线程上下文中

  26. 26

    如何在C#上下文中引用包含单引号的F#名称?

  27. 27

    在C#中的动态上下文中使用关键字

  28. 28

    关键字,这在C#的当前上下文中不可用

  29. 29

    名称“ Log”在当前上下文中不存在c#

热门标签

归档