有没有正确的方法来取消异步任务?

2024-03-10

我遇到了如何正确取消异步任务的问题。

这是一些草稿。

我的入口点运行两个异步任务。第一个任务做了一些“长时间”的工作,第二个任务取消了它。

入口点:

private static void Main()
{
    var ctc = new CancellationTokenSource();

    var cancellable = ExecuteLongCancellableMethod(ctc.Token);

    var cancelationTask = Task.Run(() =>
    {
        Thread.Sleep(2000);

        Console.WriteLine("[Before cancellation]");

        ctc.Cancel();
    });

    try
    {
        Task.WaitAll(cancellable, cancelationTask);
    }
    catch (Exception e)
    {
        Console.WriteLine($"An exception occurred with type {e.GetType().Name}");
    }
}

返回可取消任务的方法:

private static Task ExecuteLongCancellableMethod(CancellationToken token)
{
    return Task.Run(() =>
    {
        token.ThrowIfCancellationRequested();

        Console.WriteLine("1st"); 
        Thread.Sleep(1000);

        Console.WriteLine("2nd");
        Thread.Sleep(1000);

        Console.WriteLine("3rd");
        Thread.Sleep(1000);

        Console.WriteLine("4th");
        Thread.Sleep(1000);

        Console.WriteLine("[Completed]");

    }, token);  
}   

我的目的是在调用取消后立即停止写入“1st”、“2nd”、“3rd”。但我得到以下结果:

1st
2nd
3rd
[Before cancellation]
4th
[Completed]

出于明显的原因,我没有收到请求取消时引发的异常。所以我尝试重写方法如下:

private static Task ExecuteLongCancellableAdvancedMethod(CancellationToken token)
{
    return Task.Run(() =>
    {
        var actions = new List<Action>
        {
            () => Console.WriteLine("1st"),
            () => Console.WriteLine("2nd"),
            () => Console.WriteLine("3rd"),
            () => Console.WriteLine("4th"),
            () => Console.WriteLine("[Completed]")
        };

        foreach (var action in actions)
        {
            token.ThrowIfCancellationRequested();

            action.Invoke();

            Thread.Sleep(1000);
        }

    }, token);
}

现在我得到了我想要的:

1st
2nd
[Before cancellation]
3rd
An exception occurred with type AggregateException

但我想创建一个 Action 委托集合并循环它并不是解决我的问题的最方便的方法。

那么正确的做法是什么呢?为什么我需要将取消标记作为第二个参数传递到 Task.Run 方法中?


The Task不会自行取消,您需要检测取消请求并彻底中止您的工作。就是这样token.ThrowIfCancellationRequested(); does.

您应该将这些检查放置在整个代码中,放置在可以完全停止执行或回滚到安全状态的位置。

在第二个示例中,您在循环的每次迭代中调用它一次,并且它工作得很好。第一个示例仅在开始时调用它一次。如果此时令牌尚未取消,任务将运行直至完成,就像您所看到的那样。

如果您将其更改为如下所示,您也会看到您期望的结果。

return Task.Run(() =>
{
    token.ThrowIfCancellationRequested();
    Console.WriteLine("1st"); 
    Thread.Sleep(1000);

    token.ThrowIfCancellationRequested();
    Console.WriteLine("2nd");
    Thread.Sleep(1000);

    token.ThrowIfCancellationRequested();
    Console.WriteLine("3rd");
    Thread.Sleep(1000);

    token.ThrowIfCancellationRequested();
    Console.WriteLine("4th");
    Thread.Sleep(1000);

    Console.WriteLine("[Completed]");

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

有没有正确的方法来取消异步任务? 的相关文章

  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 枚举扩展方法

    在vs2008中 是否可以编写适用于任何枚举的扩展方法 我知道您可以针对特定枚举编写扩展方法 但我希望能够使用单个扩展方法对每个枚举进行处理 这可能吗 是的 只需针对基础进行编码Enum类型 例如 public static void So
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • Node.js 中的异步或步骤

    我无法让我的异步代码与 node js 一起使用 尝试异步和步骤库 代码仅返回第一个函数 似乎没有执行其余函数 我究竟做错了什么 thanks var step require step step function f1 console l
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • VB.NET 中的静态方法实现

    我很困惑Static在 VB NET 中的实现 在 C 中 我们可以创建静态类和静态方法来为我们的应用程序编写实用方法 现在 VB NET 让我们创建Module代替静态类 如果我们在模块中创建一个方法 默认情况下它会变成静态的 但在我的应
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat

随机推荐

  • 部分多键映射的数据结构?

    我的数据由映射到值的键组成 如下所示 Key Value 0 0 0 0 a 0 0 0 1 b 0 1 0 1 c 0 1 1 0 d 我正在寻找一种可以有效地对键执行搜索查询的数据结构 其中查询可以是完整或部分指定键 例如 0 0 0
  • 从 WP7 上的 xna 游戏启动 Internet Explorer

    我想知道是否可以从 Windows Phone 7 上运行的 XNA 游戏启动 Internet Explorer 我想将我的玩家重定向到我的网站 此致 我相信您仍然可以使用Web浏览器任务 http msdn microsoft com
  • ClojureScript 地图查找速度慢

    我有一个简单的地图 def my map 1 2 3 1 1 2 4 5 3 4 2 3 4 5 3 3 5 2 5 6 9 2 1 5 8 3 1 6 我用来执行查找的 然而 这表现得相当差 time doseq x range 500
  • Webpack 长期缓存

    Scenario 我正在尝试使用 webpack 将我的供应商脚本与我的应用程序脚本分开捆绑 尝试1 index js var require lodash console log webpack config js var path re
  • 如何在没有 Django 其余部分的情况下使用 Django 模板?

    我想在我的 Python 代码中使用 Django 模板引擎 但我没有构建基于 Django 的网站 如果没有 settings py 文件 和其他文件 并且必须设置 DJANGO SETTINGS MODULE 环境变量 如何使用它 如果
  • 如何获得 Java 软件商业许可? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我用 Java 编写了一个基于桌面的会计软件 我想放置密钥或许可证或其他类型的安全措施来防止客户端重新分发软件 我只是想知道该怎么办
  • 当对三个整数使用两次 = 运算符时,会发生什么? [复制]

    这个问题在这里已经有答案了 这是做什么的 int x 1 int y 2 int z 3 x y z 我在一些开源项目中遇到过多种此类事情 并且一直对它们感到困惑 我的意思是 运算符在三个整数上使用两次 即x y z 我需要理解这一点 谢谢
  • Visual Studio 无法在 Windows 10 上正确安装

    我将我的笔记本电脑升级到 Windows 10 无预览版 真正的东西 然后我安装了 Visual Studio Community Edition 2015 我已经安装了 VS 2013 这样我就可以开始使用 Cordova 功能 安装过程
  • 使用 p 值的逐步回归删除 p 值不显着的变量

    我想表演一个逐步线性回归 using p values作为选择标准 例如 在每个步骤中删除具有最高即最不显着 p 值的变量 当所有值均由某个阈值定义的显着时停止alpha 我完全知道我应该使用 AIC 例如命令step or stepAIC
  • 获取当前function()作用域的所有变量

    我有问题 我想获取当前的函数范围 我有这个示例代码 我工作正常 function nittle var Pen new Dot Generated dynamical through eval for key in window if wi
  • 使用 Boto3 从 S3 下载文件夹

    Using Boto3 Python SDK 我能够使用该方法下载文件bucket download file 有没有办法下载整个文件夹 Answer recommended by AWS collectives aws Collectiv
  • Python:如何使用 xlwt 编写复数到 Excel?

    我正在尝试使用以下命令将 Python 列表写入 Excel 文件xlwt图书馆 import xlwt from tempfile import TemporaryFile book xlwt Workbook sheet1 book a
  • 调用静态 JNI 方法从 C++ 返回字符串

    我正在尝试在Android中调用以下java方法 public static String getLevelFile String levelName body 从 C 使用以下 jni 代码 JniMethodInfoJavaApi me
  • 调用window.location.href后如何执行脚本?

    我有一个脚本可以将用户重定向到另一个页面 我想在新页面完全加载后将一些内容加载到新页面上的 div 中 我怎样才能做到这一点 以下不起作用 function goToPage window location href http www my
  • 如何在bash中测试变量是否以字符串开头?

    对于固定的前缀长度 我可以这样做 a filename 0 2 a echo temporary emacs file 对于任意前缀如何做到这一点 有更干净的方法吗 s 运算符在右操作数中采用模式 var 123 1234 var
  • 包设置不会传播到分布式的工作人员

    Info julia version julia version 1 6 0 lscpu root MyPackage lscpu Architecture x86 64 CPU op mode s 32 bit 64 bit Byte O
  • 图像具有绝对路径 - 如何在 Laravel Mix 中使用子目录 URL

    我的 Laravel Mix 应用程序将放置在服务器上的子目录中 例如 http localhost pat os server public http localhost pat os server public 我的 vue 组件中的图
  • C# 中 if 语句的性能 [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我只是想确定在具有大量迭代的循环中使用每个 if 语句对 C 应用程序性能的影响 我还没有找到与此相关的主题 因此我创建了这个主题 对于测试
  • 如何使用 MOQ 对象测试 Ninject ConstructorArguments?

    我最近一直在做我的第一个测试驱动开发项目 并一直在学习 Ninject 和 MOQ 这是我第一次尝试这一切 我发现 TDD 方法发人深省 Ninject 和 MOQ 也很棒 我正在从事的项目并不是特别适合 Ninject 因为它是一个高度可
  • 有没有正确的方法来取消异步任务?

    我遇到了如何正确取消异步任务的问题 这是一些草稿 我的入口点运行两个异步任务 第一个任务做了一些 长时间 的工作 第二个任务取消了它 入口点 private static void Main var ctc new Cancellation