对于异步Task,为什么需要Wait()来捕获OperationCanceledException?

2024-03-22

我正在遵循示例代码here http://msdn.microsoft.com/en-us/library/dd997396.aspx了解异步任务。我修改了代码以编写任务工作与主要工作的一些输出。输出将如下所示:

我注意到,如果删除 Wait() 调用,程序会以相同的方式运行,只是我无法捕获取消任务时引发的异常。有人可以解释一下幕后发生了什么需要 Wait() 才能命中 catch 块吗?

一个警告,Visual Studio 调试器将错误地停止在Console.WriteLine(" - task work");带有消息“OperationCanceledException 未由用户代码处理”的行。发生这种情况时,只需单击“继续”或按 F5 即可查看程序的其余部分运行。看http://blogs.msdn.com/b/pfxteam/archive/2010/01/11/9946736.aspx http://blogs.msdn.com/b/pfxteam/archive/2010/01/11/9946736.aspx了解详情。

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
class Program
{
  static void Main()
  {
     var tokenSource = new CancellationTokenSource();
     var cancellationToken = tokenSource.Token;

    // Delegate representing work that the task will do.
     var workDelegate 
            = (Action)
              (
                () =>
                   {
                       while (true)
                       {
                          cancellationToken.ThrowIfCancellationRequested(); 
              // "If task has been cancelled, throw exception to return"

          // Simulate task work
                  Console.WriteLine(" - task work"); //Visual Studio  
           //erroneously stops on exception here. Just continue (F5). 
           //See http://blogs.msdn.com/b/pfxteam/archive/2010/01/11/9946736.aspx
                          Thread.Sleep(100);
                       }
                   }
              );


     try
     {
     // Start the task
         var task = Task.Factory.StartNew(workDelegate, cancellationToken);

      // Simulate main work
         for (var i = 0; i < 5; i++)
         {
             Console.WriteLine("main work");
             Thread.Sleep(200);
         }

       // Cancel the task
         tokenSource.Cancel();

       // Why is this Wait() necessary to catch the exception?
       // If I reomve it, the catch (below) is never hit, 
       //but the program runs as before.
          task.Wait();
     }
     catch (AggregateException e)
     {
         Console.WriteLine(e.Message);
         foreach (var innerException in e.InnerExceptions)
         Console.WriteLine(innerException.Message);
     }

     Console.WriteLine("Press any key to exit...");
     Console.ReadKey();
   }
}

当异常被抛出时ThrowIfCancellationRequested,它传播出你的Task代表。此时,它被框架捕获并添加到该异常的列表中Task。同时,那Task被过渡到Faulted state.

理想情况下,您想要观察您的所有Task例外情况。如果您正在使用Task作为基于任务的异步模式的一部分,那么在某些时候您应该await the Task,这会传播第一个异常Task。如果您正在使用Tasks 作为任务并行库的一部分,那么在某个时候你应该调用Wait or Task<T>.Result,它传播所有异常Task,包裹在AggregateException.

如果您没有观察到Task例外,那么当Task完成后,运行时间将提高TaskScheduler.UnobservedTaskException然后忽略异常。 (这是 .NET 4.5 的行为;4.5 之前的行为会引发UnobservedTaskException然后终止该进程)。

在您的情况下,您不会等待任务完成,因此您退出了 try/catch 块。一段时间之后,UnobservedTaskException引发,然后忽略异常。

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

对于异步Task,为什么需要Wait()来捕获OperationCanceledException? 的相关文章

  • C 程序从连接到系统的 USB 设备读取数据

    我正在尝试从连接到系统 USB 端口的 USB 设备 例如随身碟 获取数据 在这里 我可以打开设备文件并读取一些随机原始数据 但我想获取像 minicom teraterm 这样的数据 请让我知道我可以使用哪些方法和库来成功完成此操作以及如
  • System.IO.IOException:由于意外>数据包格式,握手失败?

    有谁知道这意味着什么 System Net WebException 底层连接已关闭 发送时发生意外错误 gt System IO IOException 由于意外 握手失败 数据包格式 在 System Net Security SslS
  • 选择列表逻辑应位于 ASP.NET MVC、视图、模型或控制器中的什么位置?

    我觉得我的问题与这个问题很接近 但我想对这样的代码应该放在哪里进行更一般的讨论 Asp Net MVC SelectList 重构问题 https stackoverflow com questions 2149855 asp net mv
  • 将字符串转换为正确的 URI 格式?

    有没有简单的方法可以将电子邮件地址字符串转换为正确的 URI 格式 Input http mywebsite com validate email 3DE4ED727750215D957F8A1E4B117C38E7250C33 email
  • 带 If 的嵌套 For 循环的时间复杂度

    void f int n for int i 1 i lt n i if i int sqrt n 0 for int k 0 k lt pow i 3 k do something 我的思考过程 执行if语句的次数 sum i 1 to
  • 将带有 glut 的点击坐标添加到向量链接列表中

    我想创建一个向量链接列表 并在 GLUT 库的帮助下获取点击的位置并将它们附加到链接列表中 这些是我写的结构 typedef struct vector int x int y Vector typedef struct VectorLis
  • 两种类型的回发事件

    1 我发现了两篇文章 每篇文章对两种类型的回发事件的分类都略有不同 一位资源说两种类型的回发事件是Changed事件 其中控件实现 IPostbackDataHandler 当数据在回发之间更改时触发 然后Raised事件 其中控件实现 I
  • 2D morton 码编码/解码 64 位

    如何将给定 x y 的莫顿代码 z 顺序 编码 解码为 32 位无符号整数 生成 64 位莫顿代码 反之亦然 我确实有 xy2d 和 d2xy 但仅适用于 16 位宽的坐标 产生 32 位莫顿数 在网上查了很多 但没有找到 请帮忙 如果您可
  • libxml2 xmlChar * 到 std::wstring

    libxml2似乎将所有字符串存储在 UTF 8 中 如xmlChar xmlChar This is a basic byte in an UTF 8 encoded string It s unsigned allowing to pi
  • 使用 WF 的多线程应用程序的错误处理模式?

    我正在写一个又长又详细的问题 但只是放弃了它 转而选择一个更简单的问题 但我在这里找不到答案 应用程序简要说明 我有一个 WPF 应用程序 它生成多个线程 每个线程执行自己的 WF 处理线程和 WF 中的错误 允许用户从 GUI 端进行交互
  • 默认析构函数做了多少事情

    C 类中的默认析构函数是否会自动删除代码中未显式分配的成员 例如 class C public C int arr 100 int main void C myC new C delete myC return 0 删除 myC 会自动释放
  • .NET 客户端中 Google 表格中的条件格式请求

    我知道如何在 Google Sheets API 中对值和其他格式进行批量电子表格更新请求 但条件格式似乎有所不同 我已正确设置请求 AddConditionalFormatRuleRequest formatRequest new Add
  • ASP.NET JQuery AJAX POST 返回数据,但在 401 响应内

    我的应用程序中有一个网页 需要调用我设置的 Web 服务来返回对象列表 这个调用是这样设置的 document ready function var response ajax type POST contentType applicati
  • 从 Delphi 调用 C# dll

    我用单一方法编写了 Net 3 5 dll 由Delphi exe调用 不幸的是它不起作用 步骤 1 使用以下代码创建 C 3 5 dll public class MyDllClass public static int MyDllMet
  • Visual Studio 2017 完全支持 C99 吗?

    Visual Studio 的最新版本改进了对 C99 的支持 最新版本VS2017现在支持所有C99吗 如果没有 C99 还缺少哪些功能 No https learn microsoft com en us cpp visual cpp
  • 受限 AppDomain 中的代码访问安全异常

    Goal 我需要在权限非常有限的 AppDomain 中运行一些代码 它不应该访问任何花哨或不安全的内容 except对于我在其他地方定义的一些辅助方法 我做了什么 我正在创建一个具有所需基本权限的沙箱 AppDomain 并创建一个运行代
  • 为什么文件更新时“如果较新则复制”不复制文件?

    我在 Visual Studio Express 中有一个解决方案 如下所示 The LogicSchemaC 中的类 将在运行时解析指定的 XML 文件 以下是在main的方法Program cs LogicSchema ls new L
  • 在 Xamarin 中获取 OutOfMemoryException

    java lang OutOfMemoryError 考虑增加 JavaMaximumHeapSize Java 执行时内存不足 java exe 我的 Visualstudio Xamarin 项目出现内存不足异常 请帮助我如何解决此问题
  • 带有私有设置器的 EFCore Base 实体模型属性 - 迁移奇怪的行为

    实体模型继承的类内的私有设置器似乎会导致 EFCore 迁移出现奇怪的问题 考虑以下示例 其中有多个类 Bar and Baz 继承自Foo 跑步时Add Migration多次命令 添加 删除private修饰符 生成的模式在多个方面都是
  • C#中为线程指定特殊的cpu

    我有 2 个线程 我想告诉其中一个在第一个 cpu 上运行 第二个在第二个 cpu 上运行 例如在具有两个 cpu 的机器中 我怎样才能做到这一点 这是我的代码 UCI UCIMain new UCI Thread UCIThread ne

随机推荐

  • std::vector 到带有自定义分隔符的字符串

    我想复制a的内容vector到一长string带有自定义分隔符 到目前为止 我已经尝试过 h string getLabeledPointsString const string delimiter cpp string Gesture g
  • 数据表到嵌套列表

    我想转换 library data table n lt 12 DT lt data table level1 rep paste0 Manu 1 2 each n 2 level2 rep paste0 Dept 1 4 each n 4
  • 验证 Tensorflow 流中是否存在该文件。使用 tf.gfile.Exists 以字符串张量作为输入

    使用 Tensorflow 我试图在读取文件之前验证文件是否存在tf read file filename 不幸的是 按照我的管道的设置方式 我正在使用以下命令动态生成文件名字符串tf命令 我使用生成文件名字符串tf string join
  • 跟踪 XWindow 协议

    是否可以使用工具跟踪 XWindow 协议 我认为wireshark将是一个很好的框架来承载这样的想法 但似乎没有支持 为了实现这个目标应该做什么 Wiresharkdoes具有剖析X Window协议的能力 但是 您首先必须能够捕获 X
  • 用于多个 Maven 模块项目的 proguard

    我在多模块 Maven 项目中有一个对 proguard 的插件引用 我的项目的功能已经过全面测试并且可以工作 直到我添加 proguard 我的项目的结构 parent pom module a pom module b pom test
  • Maven - 添加集成测试

    尝试将 Maven 构建中的测试拆分为单元测试和集成测试 我正在使用故障安全插件来运行集成测试 并尝试使用 build helper maven plugin 从 src it java 目录添加集成测试 当我尝试进行构建时出现错误 但我看
  • 复制Mysql数据库的数据库结构

    我正在使用 MySql 5 1 数据库 我创建了一个项目数据库 模板数据库 并希望每次用户创建新项目时从应用程序创建同一数据库的副本 如何复制并创建相同结构的新数据库 这样做的命令是什么 如果您只想将表结构等从一个数据库复制到另一个数据库
  • WooCommerce 中的多个订单

    我想在类别页面中按平均评分 DESC 然后按价格 ASC 订购产品 id avgrating price 1 4 10 2 4 5 3 5 7 顺序 3 2 1 所以我尝试了 args meta key wc average rating
  • Flex:跨分辨率应用

    What is the best way to create applications in Flex AIR which look and feel the same irrespective of the screen resoluti
  • Django 接受一个整数到 CharField 中

    我正在学习 django 并创建了一个Page form class像这样 from django import forms class Page forms Form title forms CharField max length 20
  • 如何让我自己的 JavaScript 函数具有必需的参数?

    当我在intellij idea中编写javascript时 我可以检查我正在调用的函数的参数 它会显示类似的内容 我不确定这是否是一个 intellij 功能 它了解标准库 或者它是否是一个 javascript 功能 可以让您将参数标记
  • FabricJS 触摸平移/缩放整个画布

    我需要在 FabricJS 画布上启用触摸缩放 平移 有些库允许在图像上执行此行为 请参阅捏缩放画布 https github com vash15 pinch zoom canvas 或通过鼠标单击事件 参见这个小提琴 http jsfi
  • 如何保持每 5 秒请求一次页面而不耗尽电池电量?

    我正在开发的 Android 应用程序需要每 5 秒在我的服务器上请求一个页面 但我担心这会消耗大量电池 有没有更简单的方法 我当前的方法是每 5 秒循环一次的服务 protected void onHandleIntent Intent
  • 如何使用 extern 在 C++ 中的源文件之间共享 Globe 变量?

    IDE 代码块 13 12 main cpp include
  • python继承:使用参数选择父类

    我在设计一些课程时遇到困难 我希望我的用户能够通过传递角色类型的参数 例如战士 向导 来使用Character 类 虚拟代码 class CharClass def init self level self level level clas
  • 在 MSTest 中如何查找要在 ClassInitialize 或 AssemblyInitialize 中运行的测试总数?

    使用 MStest 我想查找排队等待运行的测试方法的总数 我应该如何捕获这个值ClassInitialize or AssemblyInitialize 方法 我唯一得到的是 TestContext 它没有测试总数的详细信息 我实际上对此有
  • 在 awk 中使用双引号[重复]

    这个问题在这里已经有答案了 该命令将打印a echo line1 a b c awk print 2 如果我将单引号更改为双引号 就像这样 它将打印整行 echo line1 a b c awk print 2 为什么 我知道我应该使用单引
  • 如何为给定模式提供关系代数?

    员工 姓名 街道 城市 作品 人名 公司名称 工资 公司 公司名称 城市 管理 人员姓名 经理姓名 查找此数据库中所有不为第一银行公司工作的员工的姓名 假设所有人都为一家公司工作 并且允许人员出现在数据库中 例如 在员工中 但不能出现在作品
  • es6模块加载是如何工作的

    我去过reading https github com systemjs systemjs about https github com systemjs systemjs ES6模块加载器 https github com ModuleL
  • 对于异步Task,为什么需要Wait()来捕获OperationCanceledException?

    我正在遵循示例代码here http msdn microsoft com en us library dd997396 aspx了解异步任务 我修改了代码以编写任务工作与主要工作的一些输出 输出将如下所示 我注意到 如果删除 Wait 调