Parallel.ForEach 与 HttpClient 和 ContinuousWith

2023-12-05

我有一个方法尝试从多个 URL 并行下载数据,并返回一个IEnumerable反序列化类型

该方法如下所示:

    public IEnumerable<TContent> DownloadContentFromUrls(IEnumerable<string> urls)
    {
        var list = new List<TContent>();

        Parallel.ForEach(urls, url =>
        {
            lock (list)
            {
                _httpClient.GetAsync(url).ContinueWith(request =>
                {
                    var response = request.Result;
                    //todo ensure success?

                    response.Content.ReadAsStringAsync().ContinueWith(text =>
                    {
                        var results = JObject.Parse(text.Result)
                            .ToObject<IEnumerable<TContent>>();

                        list.AddRange(results);
                    });
                });
            }
        });

        return list;
    }

在我的单元测试中(我存根 _httpClient 以返回一组已知的文本)我基本上得到

序列不包含元素

这是因为该方法在任务完成之前返回。

如果我在 .ContinueWith() 调用末尾添加 .Wait() ,它就会通过,但我确信我在这里滥用了 API...


如果您想要使用 HttpClient.GetAsync 方法并行下载的阻塞调用,那么您应该像这样实现它:

public IEnumerable<TContent> DownloadContentFromUrls<TContent>(IEnumerable<string> urls)
{
    var queue = new ConcurrentQueue<TContent>();

    using (var client = new HttpClient())
    {
        Task.WaitAll(urls.Select(url =>
        {
            return client.GetAsync(url).ContinueWith(response =>
            {
                var content = JsonConvert.DeserializeObject<IEnumerable<TContent>>(response.Result.Content.ReadAsStringAsync().Result);

                foreach (var c in content)
                    queue.Enqueue(c);
            });
        }).ToArray());
    }

    return queue;
}

这将创建一组任务,每个 Url 对应一个任务,代表 GetAsync/Deserialize 操作。这是假设 Url 返回 TContent 的 Json 数组。空数组或单个成员数组可以很好地反序列化,但单个无数组对象则不行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Parallel.ForEach 与 HttpClient 和 ContinuousWith 的相关文章

随机推荐

  • 将输入字段移动到跨度顶部

    我有一个跨度作为我的输入字段的标签 选中后 标签将位于输入字段上方 我的问题是 当您尝试单击输入字段时 标签位于输入字段的 前面 并阻止您选择它 我尝试使用 z 索引修复它 但这似乎不起作用 有人可以帮我将输入字段放在跨度前面吗 input
  • ASP CustomValidator,错误后前进到回发

    我有一个 ASP NET 页面 其中包含 ASP 验证器 必填字段 正则表达式等 以及用于附加验证的 Java 脚本函数 例如 检查第二个日期是否大于第一个日期等 我通常这样做
  • 下载mp3文件并存储在应用程序目录中

    在我的 Android 项目中 我需要以编程方式从 google 驱动器下载网址下载 mp3 文件并将其存储在应用程序沙箱中 然后 应用程序可以有播放选项在本地播放该音频 如何实现从服务器下载 mp3 文件并将其本地存储在应用程序中 稍后
  • 如何使用 SSIS 包中的 Foreach 循环容器选择最近创建的文件夹?

    我在 SSIS 方面遇到了一个有趣的挑战 使用 for each 文件枚举器 我需要选择最近创建的子文件夹 然后迭代每个文件 也许举个例子会更好地解释 这些文件夹看起来像这样 c 数据 2011 0703 c 数据 2011 0626 c
  • Python file.tell 给出错误的值位置

    我正在尝试使用 Python 从现有文件中提取多个位置 这是我当前用于提取位置的代码 self fh open fileName r p re compile regGen regPorSnip begin for line in self
  • 根据屏幕分辨率更改表单的分辨率(不更改显示器分辨率并使用最大化屏幕选项)

    我在论坛上进行了搜索 并尝试了一些方法 但它们似乎并没有真正起作用 让我列出我的问题 我的笔记本电脑的屏幕分辨率非常高 1400x1050 我正在以此为基础设计我的应用程序 我的同事在他的笔记本电脑 分辨率较低 上进行了尝试 但该应用程序不
  • 纸浆得到的结果是问题不可行,而问题不可行

    我正在尝试用纸浆解决作业问题 代码的基本部分如下 set I range 1 numberOfPoints set J range 1 numberOfCentroids tau 0 15 Q 15 decision variable x
  • pip 不会安装 .WHL 文件

    当我尝试通过输入 cmd 从 gohike 安装任何 WHL 时C Users owner Downloads gt pip install TA Lib 0 4 9 cp27 none win amd64 WHL我得到这个打印出来 Pro
  • 调用方法时出错。无法启动 JVM - 本机包将构建但无法启动

    谁能更具体地说明我的问题所在以及如何解决它 我在跑 Windows 7的 Eclipse Mars 2 版本 4 5 2 我已经反复严格按照 Marco 的 code makery ch 教程 code makery ch library
  • 即使设备使用 WiFi,iOS 也会检查蜂窝技术是否可用

    这里需要一些帮助 我需要检测 iOS 设备是否 在某个时刻 具有蜂窝功能 无论是哪一个 我尝试使用可达性类别 但当用户连接到 WiFi 时问题就开始了 因为如果是这样的话 可达性无法检测到蜂窝网络 我也尝试使用这段代码 CTTelephon
  • 了解 jquery 回调

    我很难理解 javascript 回调应该如何工作 我使用以下代码从 MySQL 数据库获取值 post getResults php x 100 y 200 function arrayOfValues alert arrayOfValu
  • PHP 中字符串的每个单词都大写吗?

    据我所知 strtolower 使字符串全部小写 而 ucfirst 使字符串的第一个字母大写 我想问一下 是否可以将字符串中的每个单词都大写 示例 string hello world 如何使其显示为 Hello World 您正在寻找u
  • 带突出显示的 QML 嵌套列表视图

    我需要创建嵌套列表视图 如下所示 并用不同的颜色突出显示主列表和子列表 我尝试过使用 ListView 突出显示 但存在诸如显示子项和父项的突出显示之类的问题 如图所示 下图 我正在使用来自的代码here有一些小的修改 这是完整的代码 im
  • tkinter 在 for 循环中创建可点击标签[重复]

    这个问题在这里已经有答案了 我想在 for 循环中创建多个可点击标签 标签的结构类似于网格 具有 row 和 col 属性 如果我单击标签 则应使用 print it 函数打印单击标签的行和列 问题是 如果我单击任何标签 在这种情况下输出始
  • 在等待输入python时更新turtle/gui

    我正在制作一个聊天程序 但遇到一个问题 屏幕仅在输入后更新 我正在使用turtle来显示聊天 我知道 turtle对于这个目的来说并不是那么好 但它非常简单 这是我循环中的代码 while True ind userlist index u
  • 模拟器上的 Ionic3(Angular4) CORS

    我正在 genymotion 模拟器上测试 Ionic 3 应用程序 顺便说一句 由于 CORS http 请求不起作用 我以为服务器有问题 但我用ionic 2应用程序检查后确认服务器没有问题 Ionic 3 应用程序的 Http 请求在
  • 根据所选国家,需要填充州和城市

    HTML
  • 防止反应悬念隐藏内容

    我用谷歌搜索 观看了很多视频来实现类似 YouTube 加载的功能 如下面的屏幕截图所示 因此 我有基于路线的导航 其中有延迟加载 因此一切正常 但在加载内容时 反应悬念将使组件显示 无 因此它在屏幕上变得不可见 只有后备组件可见 我想让内
  • 在没有jquery的情况下更改页面滚动时的背景颜色?

    我试图让过渡工作 以便背景颜色根据页面 即位置淡入另一种颜色 由具有相同类的div触发 在这里找到了一些js http codepen io Funsella pen yLfAG 它在桌面上完全按照我想要的方式工作 但它在 iPad 上崩溃
  • Parallel.ForEach 与 HttpClient 和 ContinuousWith

    我有一个方法尝试从多个 URL 并行下载数据 并返回一个IEnumerable反序列化类型 该方法如下所示 public IEnumerable