为什么这段代码是同步运行的?

2024-01-10

我试图通过代码来理解并发性。我有一个代码片段,我认为它是异步运行的。但是当我放入 debug writeline 语句时,我发现它正在同步运行。有人可以解释我需要做什么不同才能使用 Task.Something 将 ComputeBB() 推送到另一个线程吗?

澄清我希望这段代码在其他线程中运行 ComputeBB,以便主线程继续运行而不会阻塞。

这是代码:

{
    // part of the calling method
     Debug.WriteLine("About to call ComputeBB");
     returnDTM.myBoundingBox = await Task.Run(() => returnDTM.ComputeBB());
     Debug.WriteLine("Just called await ComputBB.");
     return returnDTM;
}

  private ptsBoundingBox2d ComputeBB()
  {
     Debug.WriteLine("Starting ComputeBB.");
     Stopwatch sw = new Stopwatch(); sw.Start();
     var point1 = this.allPoints.FirstOrDefault().Value;
     var returnBB = new ptsBoundingBox2d(
        point1.x, point1.y, point1.z, point1.x, point1.y, point1.z);
     Parallel.ForEach(this.allPoints,
        p => returnBB.expandByPoint(p.Value.x, p.Value.y, p.Value.z)
        );
     sw.Stop();
     Debug.WriteLine(String.Format("Compute BB took {0}", sw.Elapsed));
     return returnBB;
  }

这是立即窗口中的输出:

About to call ComputeBB
Starting ComputeBB.
Compute BB took 00:00:00.1790574
Just called await ComputBB.

澄清如果它确实是异步运行的,那么它将按以下顺序运行:

About to call ComputeBB
Just called await ComputBB.
Starting ComputeBB.
Compute BB took 00:00:00.1790574

但事实并非如此。

阐述调用代码具有如下签名: private static async Task loadAsBinaryAsync(string fileName) 不过,在下一个级别,我尝试停止使用异步。所以这是从上到下的调用堆栈:

  static void Main(string[] args)
  {
      aTinFile = ptsDTM.CreateFromExistingFile("TestSave.ptsTin");
      // more stuff
  }

  public static ptsDTM CreateFromExistingFile(string fileName)
  {
     ptsDTM returnTin = new ptsDTM();
     Task<ptsDTM> tsk = Task.Run(() => loadAsBinaryAsync(fileName));
     returnTin = tsk.Result;  // I suspect the problem is here.
     return retunTin;
  }

  private static async Task<ptsDTM> loadAsBinaryAsync(string fileName)
  {
      // do a lot of processing
     Debug.WriteLine("About to call ComputeBB");
     returnDTM.myBoundingBox = await Task.Run(() => returnDTM.ComputeBB());
     Debug.WriteLine("Just called await ComputBB.");
     return returnDTM;
  }

我有一个代码片段,我认为它是异步运行的。但是当我放入 debug writeline 语句时,我发现它正在同步运行。

await习惯于异步等待操作完成。这样做时,它将控制权交还给调用方法,直到完成。

我需要做什么不同的事情才能将 ComputeBB() 推到另一个线程上

它已经在线程池线程上运行。如果您不想以“一劳永逸”的方式异步等待,don't await表达方式。请注意,这将对异常处理产生影响。所提供的委托内部发生的任何异常都将在给定的内部捕获Task,如果你不这样做await,他们有可能会未经处理。

Edit:

我们看一下这段代码:

public static ptsDTM CreateFromExistingFile(string fileName)
{
   ptsDTM returnTin = new ptsDTM();
   Task<ptsDTM> tsk = Task.Run(() => loadAsBinaryAsync(fileName));
   returnTin = tsk.Result;  // I suspect the problem is here.
   return retunTin;
}

您当前正在做的事情是在使用时同步阻塞tsk.Result。另外,由于某种原因你打电话给Task.Run两次,每种方法一次。那是不必要的。如果您想退回您的ptsDTM实例来自CreateFromExistingFile, 你不得不await这是无法回避的。 “即发即忘”的执行根本不关心结果。它只是想开始它需要的任何操作,如果失败或成功通常不需要担心。这里的情况显然不是这样。

你需要做这样的事情:

private PtsDtm LoadAsBinary(string fileName)
{
   Debug.WriteLine("About to call ComputeBB");
   returnDTM.myBoundingBox = returnDTM.ComputeBB();
   Debug.WriteLine("Just called ComputeBB.");

   return returnDTM;
}

然后在调用堆栈上方的某个地方,您实际上不需要CreateFromExistingFiles,只需调用:

Task.Run(() => LoadAsBinary(fileName));

需要的时候。

另外,请阅读C# 命名约定 https://msdn.microsoft.com/en-us/library/ms229045%28v=vs.110%29.aspx,您目前没有关注。

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

为什么这段代码是同步运行的? 的相关文章

  • 未提供参数时如何指定 C# System.Commandline 行为?

    在我的控制台应用程序中 当未提供控制台参数时 将执行我指定列表 在本例中为参数 3 的任何处理程序 调用该处理程序时 布尔参数设置为 false 但对我来说 根本不调用它更有意义 如何防止这种情况发生并显示帮助文本 using System
  • 确保 StreamReader 不会挂起等待数据

    下面的代码读取从 tcp 客户端流读取的所有内容 并且在下一次迭代中它将仅位于 Read 上 我假设正在等待数据 我如何确保它不会在没有任何内容可供读取时返回 我是否必须设置低超时 并在失败时响应异常 或者有更好的办法吗 TcpClient
  • ClickOnce 应用程序错误:部署和应用程序没有匹配的安全区域

    我在 IE 中使用 FireFox 和 Chrome 的 ClickOnce 应用程序时遇到问题 它工作正常 异常的详细信息是 PLATFORM VERSION INFO Windows 6 1 7600 0 Win32NT Common
  • 使用 LINQ2SQL 在 ASP.NET MVC 中的各种模型存储库之间共享数据上下文

    我的应用程序中有 2 个存储库 每个存储库都有自己的数据上下文对象 最终结果是我尝试将从一个存储库检索到的对象附加到从另一个存储库检索到的对象 这会导致异常 Use 构造函数注入将 DataContext 注入每个存储库 public cl
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 获取两个工作日之间的天数差异

    这听起来很简单 但我不明白其中的意义 那么获取两次之间的天数的最简单方法是什么DayOfWeeks当第一个是起点时 如果下一个工作日较早 则应考虑在下周 The DayOfWeek 枚举 http 20 20 5B1 5D 3a 20htt
  • 如何使用 LINQ2SQL 连接两个不同上下文的表?

    我的应用程序中有 2 个数据上下文 不同的数据库 并且需要能够通过上下文 B 中的表的右连接来查询上下文 A 中的表 我该如何在 LINQ2SQL 中执行此操作 Why 我们正在使用 SaaS 产品来跟踪我们的时间 项目等 并希望向该产品发
  • Apollo graphql 将标头设置为 authmiddleware 不起作用

    我正在使用react native和apollo客户端 如果我尝试通过存储在AsyncStorage中的jwt设置标头 它似乎不起作用 其他不需要标头的解析器工作得很好 我的代码如下所示 import ApolloClient from a
  • Android 中的处理程序与异步调用

    目前我正在使用处理程序来调用 Web 服务方法以使其在后台运行 问题是它需要更多的时间来给出响应 在性能方面似乎更昂贵 现在我计划使用异步调用 哪一个是最好的 Android 中的处理程序和异步调用有什么区别 请帮我想出一个最好的解决方案
  • Azure 辅助角色“请求输入之一超出范围”的内部异常。

    我在辅助角色中调用 CloudTableClient CreateTableIfNotExist 方法 但收到一个异常 其中包含 请求输入之一超出范围 的内部异常 我做了一些研究 发现这是由于将表命名为非法表名引起的 但是 我尝试为我的表命
  • C# 中的合并运算符?

    我想我记得看到过类似的东西 三元运算符 http msdn microsoft com en us library ty67wk28 28VS 80 29 aspx在 C 中 它只有两部分 如果变量值不为空 则返回变量值 如果为空 则返回默
  • 外键与独立关系 - Entity Framework 5 有改进吗?

    我读过了several http www ladislavmrnka com 2011 05 foreign key vs independent associations in ef 4 文章和问题 https stackoverflow
  • “接口”类似于 boost::bind 的语义

    我希望能够将 Java 的接口语义与 C 结合起来 起初 我用过boost signal为给定事件回调显式注册的成员函数 这非常有效 但后来我发现一些函数回调池是相关的 因此将它们抽象出来并立即注册所有实例的相关回调是有意义的 但我了解到的
  • 为什么 gcc 抱怨“错误:模板参数 '0' 的类型 'intT' 取决于模板参数”?

    我的编译器是gcc 4 9 0 以下代码无法编译 template
  • 使用 C# 读取 Soap 消息

  • 不同类型指针之间的减法[重复]

    这个问题在这里已经有答案了 我试图找到两个变量之间的内存距离 具体来说 我需要找到 char 数组和 int 之间的距离 char data 5 int a 0 printf p n p n data 5 a long int distan
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装
  • 无法接收 UDP Windows RT

    我正在为 Windows 8 RT 编写一个 Windows Store Metro Modern RT 应用程序 需要在端口 49030 上接收 UDP 数据包 但我似乎无法接收任何数据包 我已按照使用教程进行操作DatagramSock
  • 如何从 ODBC 连接获取可用表的列表?

    在 Excel 中 我可以转到 数据 gt 导入外部数据 gt 导入数据 然后选择要使用的数据源 然后在提供登录信息后 它会给我一个表格列表 我想知道如何使用 C 以编程方式获取该列表 您正在查询什么类型的数据源 SQL 服务器 使用权 看
  • 如何将 PostgreSql 与 EntityFramework 6.0.2 集成? [复制]

    这个问题在这里已经有答案了 我收到以下错误 实体框架提供程序类型的 实例 成员 Npgsql NpgsqlServices Npgsql 版本 2 0 14 2 文化 中性 PublicKeyToken 5d8b90d52f46fda7 没

随机推荐

  • liquibase - 变更集的执行顺序

    据我了解 Liquibase 根据更改日志中写入的顺序执行更改集 我希望变更集以另一个顺序运行 有没有办法改变变更集的执行顺序 如果能及时回复我的问题 我将不胜感激 Liquibase 中变更日志的顺序是根据需要部署 执行 更改的顺序 Li
  • 在 django-rest-framework-jwt 中存储超过默认信息

    我正在使用 Django 版本 1 8 并使用 django rest framework jwt 进行身份验证 身份验证后 我们的应用程序将返回前端信息 from rest framework jwt settings import ap
  • 如何将 uuid 添加到 log4j 以登录文件?

    我有这个 log4j2 xml 文件
  • 如何将本地文件上传到Carrierwave模型?

    我使用 Carrierwave 来处理图像上传 但我没有使用表单 而是使用服务器中的本地文件 我怎样才能做到这一点 user User first image path tmp pic s7b28 jpg user image image
  • chrono::month 和 chrono::months 之间有什么区别

    C 20 chrono 类型 值之间有什么区别month 7 and months 7 有两个如此相似的名字是不是很混乱 是的 两者兼而有之可能会令人困惑month and months当第一次遇到这个库时 然而 该库中有一致的命名约定 有
  • python中while循环的多个条件

    我遇到了问题 包括多个语句while在Python中循环 它在单个条件下工作得很好 但是当我包含多个条件时 循环不会终止 我在这里做错了什么吗 name raw input Please enter a word in the senten
  • 使用 mongodb java 驱动程序运行本机 mongodb 查询

    我想用java执行CRUD操作updateOne updateMany or deleteMany 等等 但是当我想与像这样的运算符一起运行时 set unset我必须导入新课程 例如Updates或创建嵌套Document对象 我想插入原
  • JAXB xjc:如果值为空,如何生成返回空的字符串代码?

    给出以下示例 xsd 片段 lt xs attribute name SEGMENT default use optional type xs string gt 当 xjc 生成包含以下内容的类时SEGMENTbean 属性 以下 get
  • 静态字符串中的非固定宽度文本 - Jasper Reports

    正如我从这篇文章以来了解到的那样 如何在 Jasper Reports 中相对于数据宽度拉伸文本字段 https stackoverflow com questions 8979134 how to stretch field horizo
  • 如何通过java打开现有文件,如.docx、.txt、.pptx?

    我想知道如何通过java打开文件 我可以像这样打开 Office 本身 try Runtime runTime Runtime getRuntime Process process runTime exec C Program Files
  • Material-UI Menu 组件仅触发最后一个 MenuItem onClick 操作

    最近我尝试使用 MaterialUI 4 3 3 的 Menu 和 MenuItem 组件实现一个简单的下拉菜单 MenuItem 上的 onclick 事件行为不正确 什么时候console log id 被调用时 每个组件都会回显示例数
  • 在 HIghcharts 中设置自定义图例项目符号(或图标)

    我正在尝试将默认的 highcharts 图例符号更改为我自己的自定义符号 我希望图例标签旁边有一个字体很棒的图标 为此 我考虑了 labelformatter labelFormatter function var on
  • std::shared_ptrs 的自定义删除器

    创建后是否可以使用自定义删除器std shared ptr不使用new 我的问题是对象创建是由工厂类处理的 并且它的构造函数和析构函数受到保护 这会产生编译错误 我不想使用new因为它的缺点 详细说明 我更喜欢创建这样的共享指针 它不允许您
  • FluentValidation 一个属性出现多个错误消息

    我正在使用 FluentValidation 验证输入值 我正在使用一种方法来验证数据库中的值 该方法根据值返回不同错误消息的整数值 1 2 和 3 如何根据方法的返回值显示错误消息 我在类作用域中创建了一个变量并设置了返回值 在下一条语句
  • 基于目录的环境变量范围-如何实现?

    我有一组工具 需要根据我正在处理的项目传递参数 我希望能够根据当前目录自动设置几个环境变量 因此 当我在目录之间切换时 我常用的环境变量也会改变 例子 让我们当前目录是 foo 因此如果我这样做 foo myscript var1 VAR1
  • Java SE 可以减少 CDI 吗?

    JSR 330 依赖注入可以应用于 Java SE 和 Java EE 环境 而 JSR 299 的标题是 Java EE 平台的上下文和依赖注入 除了严格面向 Java EE 的功能之外 哪些 CDI 功能对 Java SE 也有意义 有
  • 如何使用 Mongoose 将 json 导入 MongoDB

    我对此有一些问题 这使得它变得棘手 所以 我正在使用 Mongoose 和 MongoLab 我可以很好地存储和检索数据 但我想要一个允许我做数据库基础种子的系统 我为集合创建了模式 但没有运行 因为没有数据 所以我似乎无法运行正常的 mo
  • XDP 卸载模式标志集不适用于 bcc

    我正在尝试运行密件抄送中提供的本教程 XDP 代码 我使用的代码是这个脚本 密件抄送 示例 网络 xdp xdp drop count py https github com iovisor bcc blob master examples
  • 启动 Android 模拟器时出错:FB::flushWindowSurfaceColorBuffer: 找不到窗口句柄 0x4

    我刚刚开始使用安卓 因此 当我尝试启动 AVD 详细信息如下 时 它不会启动 只是暂时黑屏 直到我厌倦它并将其关闭 我安装了 intelhaxm 并禁用了 hyper v 这是我从控制台得到的日志 2014 07 28 20 02 52 a
  • 为什么这段代码是同步运行的?

    我试图通过代码来理解并发性 我有一个代码片段 我认为它是异步运行的 但是当我放入 debug writeline 语句时 我发现它正在同步运行 有人可以解释我需要做什么不同才能使用 Task Something 将 ComputeBB 推送