异步方法恢复后值未更新

2024-03-13

看这段代码:

public class SharedData
{
    public int Value { get; set; }
}

void button1_Click(object sender, EventArgs e)
{
    AAA();
}

async Task BBB(SharedData data)
{
    await Task.Delay(TimeSpan.FromSeconds(1));
    MessageBox.Show(data.Value.ToString()); //<---- I always see 0 here,
    data.Value = data.Value + 1;
}

async Task<int> AAA()
{
    SharedData data = new SharedData();
    var task1 = BBB(data);
    var task2 = BBB(data);
    var task3 = BBB(data);

    await Task.WhenAll(task1, task2, task3);
    MessageBox.Show(data.Value.ToString());  //<--- this does show 3
    return data.Value;
}

这是一个 GUI(Windows 窗体)应用程序,这意味着只有一个线程执行每一行代码。

All BBB(data)调用速度非常快,无需等待。 每个BBB调用进入 BBBmethod , sees await它不会完成并返回(到 AAA)。

现在,当一秒(大约)过去后,所有的延续都会发生在 GUI 线程中.

Question

延续不会同时发生,因为它是 GUI 线程。 所以之前的声明:

data.Value = data.Value + 1;

一定发生过。

换句话说 ,

我知道所有BBBs 以相同的初始值调用data,但延续不会同时发生

GUI 线程最终必须运行:

continuation #1

 MessageBox.Show(data.Value.ToString()); 
 data.Value = data.Value + 1; //So this basically should do 0-->1
....

continuation #2

 MessageBox.Show(data.Value.ToString()); // Why data.Value still "0" ??
 data.Value = data.Value + 1;  
....

continuation #3

 MessageBox.Show(data.Value.ToString()); // Why data.Value still "0" ??
 data.Value = data.Value + 1;

看起来延续不是作为一个整体而是作为共享量子来安排的?


发生这种情况是因为您正在使用MessageBox.Show调试打印和显示模式消息框会阻止代码流,但不会阻止 UI 线程(否则您无法与消息框交互)。

因此,当第一个延续通过显示消息框“阻止”时,下一个延续可以运行,然后是第三个。它们都通过显示消息框而被“阻止”,但 UI 线程本身并未被“阻止”。

这就是为什么他们都表现出0只有当您释放消息框时,它们才能继续运行并增加变量。

您可以看到,如果使用打印该值Console.WriteLine在显示消息框之前:

async Task BBB(SharedData data)
{
    await Task.Delay(TimeSpan.FromSeconds(1));
    Console.WriteLine(data.Value);
    MessageBox.Show(data.Value.ToString());
    data.Value = data.Value + 1;
}

你会注意到0在 1 秒之后,而不是在您关闭消息框之后,所有延续都会打印 3 次。

基本上,延续并发运行,但不是使用同一线程并行运行因为MessageBox.Show在他们中。

如果你使用Console.WriteLine代替MessageBox.Show您将看到该值一次递增一个:

async Task BBB(SharedData data)
{
    await Task.Delay(TimeSpan.FromSeconds(1));
    Console.WriteLine(data.Value);
    data.Value = data.Value + 1;
}

Output:

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

异步方法恢复后值未更新 的相关文章

  • 测试 hdf5/c++ 中的组是否存在

    我正在打开一个现有的 HDF5 文件来附加数据 我想向那个叫做的小组保证 A存在以供后续访问 我正在寻找一种简单的方法来创建 A有条件地 如果不存在则创建并返回新组 或者返回现有组 一种方法是测试 A存在 我怎样才能高效地做到这一点 根据
  • .NET 可移植类库中的 .ToShortDateString 发生了什么

    我想知道为什么没有 ToShortDateString在 NET 可移植类库中 我有 2 个项目 Silverlight 和常规 NET 类库 使用相同的代码 并且代码涉及调用 ToShortDateString on a DateTime
  • 我应该在单元测试中使用 AutoMapper 吗?

    我正在为 ASP NET MVC 控制器方法编写单元测试 这些控制器依赖于IMapper 我创建的用于抽象 AutoMapper 的接口 使用 Castle Windsor 通过构造函数注入传入 动作方法使用IMapper从领域对象映射到
  • 阅读 Stack Overflow RSS 源

    我正在尝试获取未回答问题的列表the feed https stackoverflow com feeds 但我在阅读时遇到困难 const string RECENT QUESTIONS https stackoverflow com f
  • 使用 VSTO 更改 Outlook 设置

    我刚刚花了大约 4 个小时试图弄清楚如何以编程方式检索 设置 Microsoft Outlook 2010 的 Outlook 设置 我所说的 设置 是指文件 选项 邮件下的设置 我想做的是检索用户设置的设置列表 自动化我们每天需要在某些消
  • 组合 Datepicker 和 Timepicker 值 Win 8.1

    我试图同时使用 Datepicker Timepicker 来返回可以存储在数据库中的 DateTime 例如 我想要安排会议的开始日期和结束日期 如果适用 我将如何将这些值组合成 SQL 数据库可以处理的正确格式 任何反馈都会很棒 我让这
  • 成员初始值设定项列表中的求值顺序是什么?

    我有一个带有一些参数的构造函数 我假设它们是按照列出的顺序初始化的 但在一种情况下 它们似乎是按相反的顺序初始化的 导致中止 当我反转参数时 程序停止中止 下面是我正在使用的语法的示例 a 之前需要初始化b 在这种情况下 你能保证这个初始化
  • 防止复制构造和返回值引用的分配

    如果我有一个函数返回对类实例的引用 但我无法控制其源 比如说list
  • 通过 mpi 发送 c++ std::vector

    我知道存储一个std vector
  • 推送 Lua 表

    我已经创建了一个Lua表C 但我不知道如何将该表推入堆栈顶部 以便我可以将其传递给 Lua 函数 有谁知道如何做到这一点 这是我当前的代码 lua createtable state libraries size 0 int table i
  • 抽象类和接口之间的区别[重复]

    这个问题在这里已经有答案了 可能的重复 接口与基类 https stackoverflow com questions 56867 interface vs base class 我不明白抽象类和接口之间的区别 我什么时候需要使用哪种字体
  • 在 C# 中赋值后如何保留有关对象的信息?

    我一直在问我的想法可能是解决方案 https stackoverflow com questions 35254467 is it possible in c sharp to get the attributes attached to
  • C++ Primer 5th Edition 错误 bool 值没有指定最小大小?

    bool 的最小大小不应该是 1 个字节吗 这有点学术性的东西 尽管它们会转换为数字 并且 与其他所有事物一样 它们最终将基本上由计算机内存中的数字表示 但布尔值不是数字 你的bool可以取值true 或值false 即使您确实需要至少 1
  • 标准 C 中的 sizeof 与 sizeof()? [复制]

    这个问题在这里已经有答案了 我看到一些直接使用 sizeof 的代码 想知道它是否是标准 C 令我惊讶的是 它运行得很好 这是一个例子 include
  • 通过 MSBuild 调用 cl.exe 时无限期挂起

    我正在尝试在我的 主要是 C 项目上运行 MSBuild 想象一下一个非常庞大的代码库 Visual Studio 2015 是有问题的工具集 Windows 7 SP1 和 VS 2015 更新 2 即使使用 m 1 从而迫使它仅使用一个
  • 在 MVVM 中,可以在视图后面的代码中访问 ViewModel 吗?

    在 MVVM 模式中 是否可以接受甚至可以访问视图代码后面的 ViewModel 属性 我有一个可观察的集合 它填充在 ViewModel 中 我需要在视图中使用它来绑定到带有链接列表的无限滚动条 IE private LinkedList
  • 在 unix 中编译 dhrystone 时出错

    我是使用基准测试和 makefile 的新手 我已经从下面的链接下载了 Dhrystone 基准测试 我正在尝试编译它 但我遇到了奇怪的错误 我尝试解决它 但没有成功 有人可以帮助我运行 dhrystone 基准测试吗 以下是我尝试编译的两
  • 如何使用 g++ 在 c++ 20 中使用模块?

    我读了这个链接https gcc gnu org wiki cxx modules https gcc gnu org wiki cxx modules并尝试从该网站复制以下示例 我已经知道这个编译器部分支持模块系统 注 我用的是windo
  • 从 C# 中的 .NET SecureString 读取单个字符?

    WPF 的PasswordBox 返回一个SecureString 它对窥探者隐藏密码 问题是你最终必须获得密码的值 而我在网上找到的建议都涉及将值复制到字符串中 这会让你回到窥探者的问题 IntPtr bstr Marshal Secur
  • C++0x 中的新 unicode 字符

    我正在构建一个 API 它允许我获取各种编码的字符串 包括 utf8 utf16 utf32 和 wchar t 根据操作系统 可能是 utf32 或 utf16 新的 C 标准引入了新类型char16 t and char32 t没有这么

随机推荐

  • 在 SQL Server 中,如何为给定表生成 CREATE TABLE 语句?

    我花了很多时间来解决这个问题 所以本着这个帖子 https stackoverflow com questions 21245 questions vs conveying information 我将其发布在这里 因为我认为它可能对其他人
  • 相当于 jQuery .is() 的 JS

    是否有 jQuery 的纯 JS 等价物 is 在现代浏览器上 我知道有querySelector方法 但我想检查节点本身 而不是查找子节点 好像matchesSelector就是我想要的 https developer mozilla o
  • 从txt文件中删除字符串

    所以基本上我想要deletetxt 文件中的字符串 using fs 输入示例 string1 string2 string3 string4 Delete string3 删除后会是这样的 string1 string2 string4
  • NLTK 中解析的英语语法

    是否有现成的英语语法可供我加载并在 NLTK 中使用 我搜索了使用 NLTK 进行解析的示例 但似乎我必须在解析句子之前手动指定语法 多谢 你可以看一下pyStat解析器 https github com emilmont pyStatPa
  • npm-link 库上的挂钩调用无效

    问题描述 我目前正在编写一个名为eformless 我用过CRA https github com facebook create react app创建一个名为的目录sandbox 我链接包的地方 当尝试使用我尝试测试的链接包启动沙盒反应
  • 向不记名令牌 json 添加更多值

    我想在用户成功登录后返回用户名 以显示在我的网络应用程序的右上角 我想用令牌返回的 json 来发送它 为了生成令牌身份验证 我使用 ASP NET Web API 和 Owin middlehawe access token blah t
  • 如何在Chrome devtools元素检查器中搜索标签+属性?

    我在 devtool 中进行了简单的搜索 但它无缘无故地急剧下降 更重要的是 如果我查看源代码并进行相同的搜索 结果数 link rel link contains rel style 或 CSS 选择器 link rel link rel
  • Windows 窗体 ListView 缺少水平滚动条

    我在表单 C VS 2005 中有一个 Windows 窗体 ListView 并将其锚定到表单的所有边缘 以便它完全填充表单 不包括状态栏 ListView 处于详细模式 并且列非常宽 绝对比显示区域宽 我有一个垂直滚动条 但没有水平滚动
  • 将记录作为函数结果从 Delphi DLL 传递到 C++

    我现在正在经历一些非常奇怪的事情 当我将结构从 C 传递到 Delphi DLL 作为参数时 一切正常 但是 一旦我想收到结果记录 我要么得到错误的值 要么得到异常 我禁用了记录的对齐 以便通过它们应该可以 这是代码 德尔福动态链接库 TS
  • jQueryUI Datepicker 上一个和下一个图标不显示

    我已将 jquery datepicker 合并到我的应用程序中 但是无论我选择什么主题 上一个 下一个图标都不会显示 我也使用了不同版本的 jquery ui js 我尝试了一些我之前看到过的项目 例如 使用 hideIfNoPrevNe
  • 需要有关将代码转换为 Matlab_extension 1 的建议

    这是之前提出的问题的扩展 link https stackoverflow com questions 20851902 need suggestion on code conversion to matlab noredirect 1 c
  • 在 Android 屏幕上显示通知

    我正在使用此代码发送本地通知 mNotificationManager NotificationManager getSystemService Context NOTIFICATION SERVICE PendingIntent cont
  • 如何在每页显示子报表的标题?

    我需要在C1Report设计器中设置什么属性才能在每个新页面上显示我的子报表的标题 Repeat true 设置该属性后 子报表不会在每个新页面上显示标题 它确实工作得很好Main Report tho 您需要在子报表的主键字段上添加分组
  • SSL_CTX_load_verify_locations 失败并显示 SSL_ERROR_NONE

    我到处搜索 但没有找到这个问题的解释 我正在运行以下命令 int ret 0 ERR clear error ret SSL CTX load verify locations ctx f 50 server SSLCACertificat
  • 如何在 Groovy 2.4 中计算 sha256 哈希值

    我正在尝试计算 Groovy 版本 2 4 16 中的 sha256 哈希值 这是 jmeter 测试的一部分 这是它支持的 Groovy 版本 我认为我无法更改它 我知道在 Groovy 2 5 中你可以使用这样的代码 https mrh
  • 如何使用javascript填写表单字段并提交?

    如果我有一个 html 文档 其大致结构是 div class headerstuff stuff div div class body div
  • 使用三元运算符而不是 IF THEN 有什么意义? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何实现全屏模式?

    在 Windows 操作系统下运行的应用程序如何实现像 Web 浏览器一样的全屏模式 它比最大化窗口和隐藏窗口装饰更复杂吗 表单样式 无 最大化 如果您指定语言 您可能会获得一些示例代码 EDIT 回应什么格雷格发布 https stack
  • 使用 ggplot2 中的 stat_poly_eq 指定每个方面的公式

    我借用了这个示例数据集here https stackoverflow com questions 44912496 geom smooth with facet grid and different fitting functions L
  • 异步方法恢复后值未更新

    看这段代码 public class SharedData public int Value get set void button1 Click object sender EventArgs e AAA async Task BBB S