UI线程有什么特别之处?

2024-02-20

假设我有一个方法fooCPU同步运行(它不调用执行 I/O 的纯异步方法,或通过调用使用其他线程来运行其代码Task.Run或类似的方式)。该方法执行一些繁重的计算 - 它受 CPU 限制。

现在我打电话fooCPU在我的程序中,而不委托它由工作线程执行。如果一行fooCPU运行需要很长时间,在完成之前不会执行其他行。例如,从 UI 线程调用它会导致 UI 线程冻结(GUI 将变得无响应)。

当我这么说时async/await是多线程的模仿。两行不同的代码在单个线程上轮流执行。如果其中一行需要很长时间才能运行,则在其完成之前不会执行其他行。,

有人告诉我,对于 UI 线程上使用的异步来说这是正确的,但对于所有其他情况(ASP.NET、线程池上的异步、控制台应用程序等)来说并非如此。

谁能告诉我这可能意味着什么? UI 线程与控制台程序的主线程有何不同?

我认为没有人希望这个论坛上的任何人继续讨论相关主题,例如它们出现在评论中,所以最好提出一个新问题。


我建议你阅读我的async介绍帖子 http://blog.stephencleary.com/2012/02/async-and-await.html;它解释了如何async and await关键词有效。然后,如果您有兴趣编写异步代码,请继续我的async最佳实践文章 https://msdn.microsoft.com/en-us/magazine/jj991977.aspx.

介绍帖子的相关部分:

异步方法的开头就像任何其他方法一样执行。也就是说,它同步运行,直到遇到“等待”(或引发异常)。

所以这就是为什么控制台代码示例中的内部方法 https://stackoverflow.com/questions/33711136/thread-returning-to-thread-pool-when-using-await(没有await)同步运行。

等待检查等待以查看它是否已经完成;如果可等待已经完成,则该方法将继续运行(同步地,就像常规方法一样)。

所以这就是为什么控制台代码示例中的外部方法 https://stackoverflow.com/questions/33711136/thread-returning-to-thread-pool-when-using-await(那是await同步的内部方法)正在同步运行。

稍后,当可等待完成时,它将执行异步方法的其余部分。如果您正在等待内置的可等待对象(例如任务),则异步方法的其余部分将在“等待”返回之前捕获的“上下文”上执行。

这个“上下文”是SynchronizationContext.Current除非是null,在这种情况下是TaskScheduler.Current。或者,更简单的版本:

这个“背景”到底是什么? 简单回答:

  1. 如果您位于 UI 线程上,那么它就是 UI 上下文。
  2. 如果您正在响应 ASP.NET 请求,那么它就是 ASP.NET 请求上下文。
  3. 否则,它通常是线程池上下文。

将所有这些放在一起,您可以想象async/await像这样工作:该方法被分成几个“块”,每个块await充当方法的分割点。第一个块始终同步运行,并且在每个分割点它可以同步或异步继续。如果它异步继续,那么它将在捕获的上下文中继续(默认情况下)。 UI 线程提供将在 UI 线程上执行下一个块的上下文。

因此,为了回答这个问题,UI 线程的特殊之处在于它们提供了SynchronizationContext该队列返回到同一个 UI 线程。

我认为没有人希望这个论坛上的任何人继续讨论相关主题,例如它们出现在评论中,所以最好提出一个新问题。

嗯,Stack Overflow 专门是not旨在成为一个论坛;这是一个问答网站。因此,这不是一个要求详尽教程的地方;而是一个地方。当您在尝试让代码正常运行时遇到困难,或者在尽一切努力研究之后仍不明白某些内容时,可以到这里来。这就是为什么对 SO 的评论(有目的地)受到限制 - 它们必须简短,没有漂亮的代码格式等。本网站上的评论旨在澄清,而不是作为讨论或论坛主题。

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

UI线程有什么特别之处? 的相关文章

  • 将 new 与 decltype 一起使用

    T t T is an implementation detail t new T want to avoid naming T to allow for flexibility t new decltype t error cannot
  • Poco c++Net:Http 从响应中获取标头

    我使用 POCO C Net 库进行 http 我想尝试制定持久缓存策略 首先 我认为我需要从缓存标头中获取过期时间 并与缓存值进行交叉检查 如果我错了 请告诉我 那么我如何从中提取缓存头httpResponse 我已经看到你可以用 Jav
  • 解析 JWT 令牌以仅获取有效负载内容,无需 C# 或 Blazor 中的外部库

    我正在使用 Blazor 编写可以访问 JWT 的客户端应用程序 我想知道一种简单的方法来读取令牌有效负载内容而不添加额外的依赖项 因为我不需要其他信息 也不需要验证令牌 我认为解析有效负载内容应该足够简单 只需将其写入方法即可 JwtTo
  • linq 中使用字符串数组 c# 的 'orderby'

    假设我有一个这样的方法定义 public CustomerOrderData GetCustomerOrderData string CustomerIDs var query from a in db Customer join b in
  • CSharpRepl emacs 集成?

    我碰巧知道莫诺CSharpRepl http www mono project com CsharpRepl 是否有 emacs csharp 模式使用它在一个窗口中运行 REPL 并像 python 模式一样在另一个窗口中编译 运行 C
  • 在 C# 中调用 C++ 库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有很多用 C 编写的库 我想从 C 调用这些库 但是 我遇到了很多问题 我想知道是否有书籍或指南告诉我如何做到这一点 Dll导入 htt
  • 如何使用 SOAP 且不使用 WSE 在 .NET 中签署 Amazon Web 服务请求

    亚马逊产品广告 API 以前称为 Amazon Associates Web Service 或 Amazon AWS 实施了一项新规则 即自 2009 年 8 月 15 日起 向其发送的所有 Web 服务请求都必须经过签名 他们在其网站上
  • 从模板切换传递的类型

    在 C 中是否可以检查传递给模板函数的类型 例如 template
  • 运行需要 MySql.Data 的内置 .NET 应用程序

    我在运行我编写的内置 NET 应用程序时遇到问题 我的应用程序使用最新的 MySql 连接器 该连接器安装在我的系统上 当我尝试将其添加为引用时 该连接器显示为 NET 4 Framwork 组件 当我在环境中以调试模式运行应用程序时 一切
  • Gwan C#,如何获取HTTP标头?

    我需要它来重写 url 以了解我正在处理哪个友好的 url 用于用户代理和其他东西 EDIT public class Gwan MethodImplAttribute MethodImplOptions InternalCall exte
  • 计算另一个表达式中的 C# 表达式

    我想在另一个表达式中使用一个表达式 Expression
  • 使用查询表达式对 List 进行排序

    我在使用 Linq 订购这样的结构时遇到问题 public class Person public int ID get set public List
  • C# 编译器不会优化不必要的强制转换

    前几天 在写答案的时候这个问题 https stackoverflow com questions 2208315 why is any slower than contains在这里 关于溢出 我对 C 编译器感到有点惊讶 它没有按照我的
  • MFC:如何设置CEdit框的焦点?

    我正在开发我的第一个简单的 MFC 项目 但我正在努力解决一个问题 想要设置所有的焦点CEdit其中一个对话框中的框 我的想法是 当打开对话框时 焦点位于第一个编辑框上 然后使用 选项卡 在它们之间交换 我看到了方法SetFocus 但我无
  • 如何使用 NPOI 按地址(A1、A2)获取 Excel 单元格值

    我有一个 Excel 单元格地址 例如 A1 A2 如何使用 C 中的 NPOI 框架以编程方式访问此单元格 我找到的一些 Java POI 示例代码 CellReference cr new CellReference A1 row my
  • 英文日期差异

    接近重复 如何计算相对时间 https stackoverflow com questions 11 how do i calculate relative time 如何在 C 中计算某人的年龄 https stackoverflow c
  • 在 OpenGL 中渲染纹理 1 到 1

    所以我想做的是使用 OpenGL 和 C 将纹理渲染到平面上 作为显示图像的一种方式 但是我需要确保在渲染纹理时没有对纹理进行任何处理 抗锯齿 插值 平滑 模糊等 这是 OpenGL 处理渲染纹理的默认方式吗 或者是否需要设置一些标志才能禁
  • 如何停止无限循环?

    我正在编写一个程序 该程序将计算三角形或正方形的面积 然后提示用户是否希望计算另一个 我的代码已经运行到可以计算任一形状的面积的程度 但随后不再继续执行代码的其余部分 例如 如果选择了正方形 则计算面积 然后返回到正方形边长的提示 我假设这
  • 如何使用placement new重新初始化该字段?

    我的课程包含字段 private OrderUpdate curOrderUpdate 我一遍又一遍地使用它 经常需要重新初始化 for int i 0 i lt entries size i auto entry entries i ne
  • 结构化绑定的用例有哪些?

    C 17 标准引入了新的结构化绑定 http en cppreference com w cpp language structured binding功能 最初是proposed http www open std org jtc1 sc

随机推荐