为什么这个异步代码有时会失败,并且只有在没有观察到的情况下才会失败?

2023-12-03

这是已经运行良好几周的原始代码。在我刚刚进行的测试中,100 次尝试中有 0 次失败。

using (var httpClient = new HttpClient())
{
    var tasks = new List<Task>();

    tasks.Add(httpClient.GetAsync(new Uri("..."))
        .ContinueWith(request =>
        {
            request.Result.Content.ReadAsAsync<IEnumerable<Foo>>()
                .ContinueWith(response =>
                {
                    foos = response.Result;
                });
        }));

    tasks.Add(httpClient.GetAsync(new Uri("..."))
        .ContinueWith(request =>
        {
            request.Result.Content.ReadAsAsync<Bar>()
                .ContinueWith(response =>
                {
                    bar = response.Result;
                });
        }));

    await Task.WhenAll(tasks);
}

此代码在 100 次尝试中失败了 9 次,其中一个或两个元组值是null.

var APIresponses = await HttpClientHelper.GetAsync
    <
        IEnumerable<Foo>,
        Bar
    >
    (
        new Uri("..."),
        new Uri("...")
    );

foos = APIresponses.Item1;
bar = APIresponses.Item2;
private static Task GetAsync<T>(HttpClient httpClient, Uri URI, Action<Task<T>> continuationAction)
{
    return httpClient.GetAsync(URI)
        .ContinueWith(request =>
        {
            request.Result.EnsureSuccessStatusCode();

            request.Result.Content.ReadAsAsync<T>()
                .ContinueWith(continuationAction);
        });
}

public static async Task<Tuple<T1, T2>> GetAsync<T1, T2>(Uri URI1, Uri URI2)
{
    T1 item1 = default(T1);
    T2 item2 = default(T2);

    var httpClient = new HttpClient();
    var tasks = new List<Task>()
    {
        GetAsync<T1>(httpClient, URI1, response =>
        {
            item1 = response.Result;
        }),
        GetAsync<T2>(httpClient, URI2, response =>
        {
            item2 = response.Result;
        })
    };

    await Task.WhenAll(tasks);

    return Tuple.Create(item1, item2);
}

将代码修改为如下所示,它再次将在 100 次尝试中失败 0 次。

    await Task.WhenAll(tasks);
    System.Diagnostics.Debug.WriteLine("tasks complete");
    System.Diagnostics.Debug.WriteLine(item1);
    System.Diagnostics.Debug.WriteLine(item2);

    return Tuple.Create(item1, item2);
}

我已经看了半个多小时了,但我不知道错误在哪里。有人看到吗?


为了解决您的评论其他问题,你很少需要混合async/await with ContinueWith。您可以在以下帮助下执行“分叉”逻辑asynclambdas,例如,问题中的代码可能如下所示:

using (var httpClient = new HttpClient())
{
    Func<Task<IEnumerable<Foo>>> doTask1Async = async () =>
    {
        var request = await httpClient.GetAsync(new Uri("..."));
        return response.Content.ReadAsAsync<IEnumerable<Foo>>();
    };

    Func<Task<IEnumerable<Bar>>> doTask2Async = async () =>
    {
        var request = await httpClient.GetAsync(new Uri("..."));
        return response.Content.ReadAsAsync<IEnumerable<Bar>>();
    };

    var task1 = doTask1Async();
    var task2 = doTask2Async();

    await Task.WhenAll(task1, task2);

    var result1 = task1.Result;
    var result2 = task2.Result;

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

为什么这个异步代码有时会失败,并且只有在没有观察到的情况下才会失败? 的相关文章

  • TestContext.DataRow["MyColumnName"] 的替代品是什么

    在 Net Core 单元测试项目中使用 MSTest 我正在尝试使用 csv 数据源来提供测试方法的数据 以前 我会在 Net Framework 测试项目中使用如下所示的内容 DataSource Microsoft VisualStu
  • 用于清理 openssl EVP_PKEY 私钥内存的 C 代码

    我开始学习 C C 中的 OpenSSL 编程 我遇到的一个问题是 如何安全地清除私钥的内存 例如 我可能有代码 EVP PKEY private key PEM read bio PrivateKey bio RSA r EVP PKEY
  • 如何从代码中隐藏 div (c#)

    我的页面上有一个 div 元素 我希望根据代码隐藏中的会话值显示 隐藏该元素 我怎样才能做到这一点 给div runat server and an id你可以在你的code behind div 在后面的代码中 theDiv Visibl
  • 模板:模板函数与类模板成员函数不能很好地配合[重复]

    这个问题在这里已经有答案了 这是我实际拥有的一些代码的最小测试用例 当它尝试评估时失败a getResult b test cpp In function void printStuff const A test cpp 6 error e
  • C# 中的序列化和对象版本控制

    如果我想序列化一个对象 我必须使用 Serializable 属性和所有成员变量将被写入该文件 我不知道如何进行版本控制 例如如果我添加一个新的成员变量 重命名变量或仅删除变量 然后打开 反序列化 文件 如何确定对象 文件版本 以便我可以正
  • 如何在 RestSharp 中使用 PUT?

    我想使用 PUT 但我只能找到如何使用 POST 的示例 我要发送的json数据是使用这个cURL命令发送的curl i H Content Type application json X PUT d status 1 http 192 1
  • 无法使用Boost.process

    我下载并打包了 1 54 0 版本的 Boost 库 我做了类似回答这个问题的一切 如何在 Visual Studio 2010 中使用 Boost https stackoverflow com questions 2629421 how
  • 将 0x1234 转换为 0x11223344

    如何高性能地将十六进制数0x1234扩展到0x11223344 unsigned int c 0x1234 b b c 0xff lt lt 4 c 0xf c 0xff0 lt lt 8 c 0xff00 lt lt 12 c 0xf00
  • `uint_fast32_t` 保证至少与 `int` 一样宽吗?

    C 标准规定整数操作数小于int将晋升为int在对它们执行任何算术运算之前 因此 对两个小于的无符号值进行运算int将使用有符号而不是无符号的数学来执行 如果需要确保使用无符号数学对 32 位操作数执行操作 例如 将两个乘积可能超过 2 的
  • 给定 X 在三次贝塞尔曲线上求 Y?

    我需要一种方法 允许我在给定 x 坐标的情况下找到三次贝塞尔曲线上的 Y 坐标 我遇到过很多地方告诉我将其视为三次函数 然后尝试找到根 我理解这一点 然而 三次贝塞尔曲线的方程是 对于 x 坐标 X t 1 t 3 X0 3 1 t 2 t
  • C# P2P聊天应用程序设计

    我想创建一个不使用显式服务器的简单聊天应用程序 主要要求是用户可以同时与许多朋友聊天 就像在 Skype 等上一样 我在这里指的不是会议聊天 而是多个单独的聊天窗口 目前 我只想要一个 LAN 消息应用程序 但如果设计能够轻松扩展到 Int
  • C语言中的积分提升和平衡有什么区别?

    积分提升和平衡有什么区别 我们是否可以总结这两条规则 即在执行任何操作 逻辑运算符 除外 之前 任何类型都至少转换为 int 或 unsigned int 类型 如果任何操作数的类型为更大 则转换为更大的类型比整数 积分促销 是旧的C90术
  • 在 C# 中使用正则表达式重复模式

    我有一串话 词黑暗王辉光我们结束你好再见低翼 我需要找到第一个单词的最后一个字母与以下单词的第一个字母匹配的单词 例如 worD Dark 我写了一个正则表达式 b w w W 1 w b 目前它成功找到连续 2 个单词 Regex Mat
  • C - 具有可变数量参数和命令行参数的函数

    我需要排序n按字典顺序排列的作为参数数量可变的函数的参数的字符串数量 在main函数中 字符串被读取为命令行参数 这是我的代码 include
  • 有没有工具可以检测 Visual C++ 6.0 上的缓冲区溢出? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 由于堆问题 我一直遇到崩溃问题 所以我猜想某个地方发生了缓冲区溢出 我如何检测它 I use Compuware 边界检查器 http w
  • 使用 Lambda 表达式从字段名称中选择不同的字段

    我需要从数据库表中获取两个字段 使用 linq to sql 检索 一个字段是日期时间 并且是固定字段 另一个字段始终是十进制 但该字段可以不同 该表保存的货币数据每天以不同的货币处理两次 因此可能具有 AM USD PM USD AM E
  • 如何在C(Linux utf8终端)中打印“盒子抽屉”Unicode字符?

    我正在尝试显示 方框图范围 2500 257F 中的 Unicode 字符 它应该是标准 utf8 Unicode 标准 版本 6 2 我根本做不到 我首先尝试使用旧的 ASCII 字符 但 Linux 终端以 utf8 显示 并且没有显示
  • 从文本文件中读取行并存储到数组中

    如何从文本文件中读取行并将其存储到数组中 例如 我有一个包含 45 行不同行的文本文件 我的尝试 int main int a 45 ifstream myfile enroll assg txt if myfile cout lt lt
  • 为什么我们从 MultiByte 转换为 WideChar?

    我习惯于处理 ASCII 字符串 但现在使用 UNICODE 我对一些术语感到非常困惑 什么是多字节字符以及什么是widechar有什么不同 多字节是指在内存中包含多个字节的字符吗 widechar只是一个数据类型来表示吗 为什么我们要从M
  • C# 4.0 动态对象和 WinAPI 接口,如 IShellItem(无需在 C# 源代码中定义它们)

    是否可以 使用 C 4 0 中的新动态关键字 使用接口 如 IShellItem 或其他 WinAPI 接口 而无需在 C 源代码中定义它们 或者至少不定义接口成员 我正在尝试类似的事情 const string IShellItemGui

随机推荐