CancellationTokenSource 的行为不符合预期

2023-11-29

在这种情况下,预期的是,如果用户通过按回车键取消任务,则另一个任务会被挂钩ContinueWith会运行,但事实并非如此,根据AggregateException尽管在中进行了显式处理,但仍会抛出ContinueWith这显然没有被执行。
请对以下内容进行澄清吗?

class Program
{
    static void Main(string[] args)
    {
        CancellationTokenSource tokensource = new CancellationTokenSource();
        CancellationToken token = tokensource.Token;

        Task task = Task.Run(() =>
        {
            while (!token.IsCancellationRequested)
            {
                Console.Write("*");
                Thread.Sleep(1000);
            }
        }, token).ContinueWith((t) =>
        {
            t.Exception.Handle((e) => true);
            Console.WriteLine("You have canceled the task");
        }, TaskContinuationOptions.OnlyOnCanceled);

        Console.WriteLine("Press any key to cancel");
        Console.ReadLine();
        tokensource.Cancel();
        task.Wait();
    }
}

让我们从几个事实开始:

  1. 当你通过一个CancellationToken作为参数Task.Run仅当取消时才有效before任务开始运行。如果任务已经在运行,它将not被取消。
  2. 取消任务after它已经开始运行,你需要使用CancellationToken.ThrowIfCancellationRequested, not CancellationToken.IsCancellationRequested.
  3. 如果任务被取消,它的Exception属性没有任何例外,并且是null.
  4. 如果延续任务由于某种原因没有运行,则意味着它已被取消。
  5. 任务包含其自身+所有子任务的异常(因此,AggregateException).

这就是您的代码中发生的情况:

任务开始运行,因为令牌未取消。它将运行直到令牌被取消。之后它将结束延续will notrun 因为它仅在前面的任务被取消时运行,而事实并非如此。当你Wait它将抛出的任务AggregateException with a TaskCanceledException因为延续被取消(如果您删除该延续,则异常将消失)。

解决方案:

您需要修复该任务,使其实际上被取消,并删除(或空检查)异常处理,因为没有异常:

var task = Task.Run(new Action(() =>
{
    while (true)
    {
        token.ThrowIfCancellationRequested();
        Console.Write("*");
        Thread.Sleep(1000);
    }
}), token).ContinueWith(
    t => Console.WriteLine("You have canceled the task"),
    TaskContinuationOptions.OnlyOnCanceled);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CancellationTokenSource 的行为不符合预期 的相关文章

  • 为什么pow函数比简单运算慢?

    从我的一个朋友那里 我听说 pow 函数比简单地将底数乘以它的指数的等价函数要慢 例如 据他介绍 include
  • ComboBox DataBinding 导致 ArgumentException

    我的几个类对象 class Person public string Name get set public string Sex get set public int Age get set public override string
  • 如何填充 ToolStripComboBox?

    我发现它很难将数据绑定到ToolStripComboBox 好像没有这个ValueMember and DisplayMember特性 怎么绑定呢 访问toolstripcombobox中包装的组合框并访问其ValueMember Disp
  • 函数参数的默认参数是否被视为该参数的初始值设定项?

    假设我有这样的函数声明 static const int R 0 static const int I 0 void f const int r R void g int i I 根据 dcl fct default 1 如果在参数声明中指
  • 为什么在 WebApi 上下文中在 using 块中使用 HttpClient 是错误的?

    那么 问题是为什么在 using 块中使用 HttpClient 是错误的 但在 WebApi 上下文中呢 我一直在读这篇文章不要阻止异步代码 https blog stephencleary com 2012 07 dont block
  • 对 std::vector 进行排序但忽略某个数字

    我有一个std vector
  • 告诉 Nancy 将枚举序列化为字符串

    Nancy 默认情况下在生成 JSON 响应时将枚举序列化为整数 我需要将枚举序列化为字符串 有一种方法可以通过创建来自定义 Nancy 的 JSON 序列化JavaScript 原始转换器 https github com NancyFx
  • 类型约束

    我有以下类层次结构 class Header IEnumerable
  • 识别 Visual Studio 中的重载运算符 (c++)

    有没有办法使用 Visual Studio 快速直观地识别 C 中的重载运算符 在我看来 C 中的一大问题是不知道您正在使用的运算符是否已重载 Visual Studio 或某些第三方工具中是否有某些功能可以自动突出显示重载运算符或对重载运
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • 在mysql连接字符串中添加应用程序名称/程序名称[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我正在寻找一种解决方案 在连接字符串中添加应用程序名称或程序名称 以便它在 MySQL Workbench 中的 客户端连接 下可见 SQL
  • 等待 IAsyncResult 函数直至完成

    我需要创建等待 IAsyncResult 方法完成的机制 我怎样才能做到这一点 IAsyncResult result contactGroupServices BeginDeleteContact contactToRemove Uri
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • 将数组作为参数传递

    如果我们修改作为方法内参数传递的数组的内容 则修改是在参数的副本而不是原始参数上完成的 因此结果不可见 当我们调用具有引用类型参数的方法时 会发生什么过程 这是我想问的代码示例 using System namespace Value Re
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • 为boost python编译的.so找不到模块

    我正在尝试将 C 代码包装到 python 中 只需一个类即可导出两个函数 我编译为map so 当我尝试时import map得到像噪音一样的错误 Traceback most recent call last File
  • 中断连接套接字

    我有一个 GUI 其中包含要连接的服务器列表 如果用户单击服务器 则会连接到该服务器 如果用户单击第二个服务器 它将断开第一个服务器的连接并连接到第二个服务器 每个新连接都在一个新线程中运行 以便程序可以执行其他任务 但是 如果用户在第一个
  • Objective-C / C 给出枚举默认值

    我在某处读到过关于给枚举默认值的内容 如下所示 typedef enum MarketNavigationTypeNone 0 MarketNavigationTypeHeirachy 1 MarketNavigationTypeMarke
  • 灵气序列解析问题

    我在使用 Spirit Qi 2 4 编写解析器时遇到一些问题 我有一系列键值对以以下格式解析
  • 不区分大小写的字符串比较 C++ [重复]

    这个问题在这里已经有答案了 我知道有一些方法可以进行忽略大小写的比较 其中涉及遍历字符串或一个good one https stackoverflow com questions 11635 case insensitive string

随机推荐

  • Tkinter IntVar 返回 PY_VAR0 而不是值

    我有一个复选按钮和一个IntVar与之关联的对象 但是当我尝试获取该值时var 我正在接收PY VAR0 这是我的代码 from tkinter import root Tk def show state print var var Int
  • 具有多个依赖项的 jQuery ajax 调用链

    我不太懂魔法deferred使用 jQuery 的对象 假设以下代码 function callWebService uri filter callback var data if filter filter data filter fil
  • jQuery animate() 更改文本

    我现在刚刚迈出了关于 jQuery animate 的第一步 我试图制作一个演示类型的东西只是为了练习 但我似乎无法使用 animate 函数更改动画中间的 div 文本 这是我当前的代码
  • pandas 中 max 的列标签

    我正在尝试从 pandas 数据框中提取行和贡献列标签中的最大值 例如 A B C D index x 0 1 2 3 y 3 2 1 0 我期望以下输出 A B C D Maxv Con index x 0 1 2 3 3 D y 3 2
  • 在 Firestore for Swift 中按时间戳传递和过滤项目

    我正在尝试在 Firestore 中传递今天的日期Timestamp在我的应用程序中 我得到这样的今天的日期 formatter dateFormat MMMM d yyyy let result formatter string from
  • 运行 Android 4.04 的 socket.connect() Galaxy Tab 2 上出现 NullPointer 异常

    我似乎在 socket connect 上遇到了这个奇怪的错误 09 18 14 41 22 968 W System err 2593 java lang NullPointerException 09 18 14 41 22 968 W
  • 我可以安装旧版本的 VS 扩展“Web Essentials 2012”吗?

    它删除了我一直依赖的 TypeScript 功能 现在我早上的工作效率看起来相当不错 我使用的是一台干净的机器 但它已经引入了新的 3 0 版本 该版本缺少我最受益的部分 您可以使用以下链接将版本恢复到 2 9 http vswebesse
  • 相当于iOS中的R

    在 android 中 我们有代表资源的 R 类 其中我们引用了所有资源 并且可以在代码中轻松访问它们 iOS 中有类似的吗 我有这个疑问 因为我希望能够定义具有不同值的多个文件 例如 ViewController1 的默认值 ViewCo
  • 将 PredicateBuilder 与 VB.NET 结合使用

    我已在单独的 C 项目中重新创建了 Predicatebuilder 类 并尝试在 VB NET 项目中使用它 但我不断收到以下错误 重载解析失败 因为没有可访问的 或 接受此数量的参数 当我像这样使用它时 Dim predicate Pr
  • XCeed PropertyGrid 自定义 IntegerUpDown

    我试图将不同的增量值分配给对象的不同字段 例如 考虑一个班级有谁int1 and int2 当我设置ShowAdvancedOptions为我的真实PropertyGrid 整数向上向下按钮放入文本框中没有问题 但我希望能够编辑数字单独增加
  • 如何在gganimate中使两帧之间的过渡时间更长

    我正在使用 gganimate 创建散点图的多个帧的动画 每个帧对应于一年 我想强调两个特定的连续帧之间的变化 以便这两个帧在其他帧中脱颖而出 但我不知道该怎么做 这是我的数据和代码的示例 structure list x 1 6 y 2
  • 如何终止 BufferedInputStream .read() 调用

    我正在编写一个程序来从服务器下载非常大的文件 2GB 我编写的程序能够恢复部分完成的下载 为了模拟糟糕的互联网连接 我在下载过程中将以太网线从路由器中拔出 不幸的是 这导致我的程序挂起以下调用 while bytesRead in read
  • 使用正则表达式验证 IP

    我需要验证格式为 000000000 到 255255255 的 IP 范围 3 组数字之间没有任何分隔符 最终 IP 所包含的三组中的每一组都应为 000 是的 用 0 填充 到 255 由于这是我的第一个 stackoverflow 条
  • 如何从远程主机的以太网地址获取其IP地址?

    我正在寻找一些 Linux 代码来从以太网地址查找 IP 地址 我想我必须做一些反向 A RP 欺骗 但我没有找到任何例子 http compnetworking about com od networkprotocolsip f conv
  • Android 谷歌地图在 Zoom 上调整标记大小

    我需要在一个较小的区域中显示大约 30 个标记 当用户更改缩放比例时 是否可以调整 Google Maps API V2 标记的大小 或者我应该使用较小的图像 提前致谢 如果你想在缩放时做一些事情 你可以创建一个扩展原始MapView的自定
  • 副SIM卡的MNC和MCC

    我知道使用TelephonyManager我们可以获得我们网络提供商的MNC和MCC TelephonyManager tel TelephonyManager getSystemService Context TELEPHONY SERV
  • 如何在Python中只打印一个新行? “\n”没有给我想要的效果

    我很清楚print n 但这在我的cmd中给出了这个结果 第一个输出 带有 原始 列表 继续到下一行 但使用 n似乎跳过了一行 我怎样才能确保print pretty函数转到下一行 而不是跳过一行 到目前为止 这是我的代码 board fo
  • 如何在 symfony yml 配置文件中从 docker 获取环境变量

    在 docker compose yml 中 mysql image mysql latest container name mysql environment MYSQL ROOT PASSWORD root MYSQL DATABASE
  • 计算两个给定日期之间的天数

    任何人都可以纠正我的脚本中的错误来计算两个日期之间的天数 日期已通过表格输入 变量信息如下 departon gt Array 0 gt 1 1 gt June 2 gt 2011 returnon gt Array 0 gt 31 1 g
  • CancellationTokenSource 的行为不符合预期

    在这种情况下 预期的是 如果用户通过按回车键取消任务 则另一个任务会被挂钩ContinueWith会运行 但事实并非如此 根据AggregateException尽管在中进行了显式处理 但仍会抛出ContinueWith这显然没有被执行 请