按时间取消任务

2023-11-21

我有一个多线程应用程序,我需要在一定时间后取消每个任务,即使在取消时,它们使用非托管资源。现在我使用以下代码(例如控制台应用程序)。在实际应用中,延迟可能发生在非托管资源中。

static void Main()
    {
        for (int i = 0; i < 10; i++)
        {
            Task.Factory.StartNew(Do, TaskCreationOptions.LongRunning);
        }

        Console.ReadLine();
    }

    private static void Do()
    {
        new Timer(Thread.CurrentThread.Abort, null, 1000, -1);

        try
        {
            Console.WriteLine("Start " + Task.CurrentId);
            Thread.Sleep(2000);
            Console.WriteLine("End " + Task.CurrentId);
        }
        catch (Exception)
        {
            Console.WriteLine("Thread Aborted " + Task.CurrentId);
        }
    }

得到结果:

enter image description here

但从安全的角度来看,我不确定这是否适合实际应用。 我还在不同的变体中使用了 CancellationToken ,但它没有给我正确的结果,因为当我使用 CancellAfter() 或 .Delay() 与时间跨度并在一定时间后取消任务时,我得到了以下结果:

static void Main()
    {
        for (int i = 0; i < 10; i++)
        {
            var clt = new CancellationTokenSource();

            Task task = new Task(() =>
            {
                Task.Delay(2000).ContinueWith(_ =>
                {
                    clt.Cancel();

                }, clt.Token);

                Do(clt.Token);

            }, clt.Token);

            task.Start();
        }

        Console.ReadLine();
    }

    private static void Do(CancellationToken cltToken)
    {
        Console.WriteLine("Start " + Task.CurrentId);

        Thread.Sleep(2500);

        if (!cltToken.IsCancellationRequested)
        {
            Console.WriteLine("End " + Task.CurrentId);
        }
        else
        {
            Console.WriteLine("Cancelled "+ Task.CurrentId);
        }
    }

enter image description here

在这种情况下,必须取消所有任务,因为 Thread.Sleep() > 分配给执行每个任务的时间。但我们可以看到有的时候执行了。

我还使用以下构造并给出相同的结果:

        static void Main()
    {
        for (int i = 0; i < 10; i++)
        {
            var clt = new CancellationTokenSource();
            clt.CancelAfter(2000);

            Task.Factory.StartNew(Do, clt.Token);

        }

        Console.ReadLine();
    }

    private static void Do(object obj)
    {
        var cltToken = (CancellationToken) obj;

        Console.WriteLine("Start " + Task.CurrentId);

        Thread.Sleep(2500);

        if (!cltToken.IsCancellationRequested)
        {
            Console.WriteLine("End " + Task.CurrentId);
        }
        else
        {
            Console.WriteLine("Cancelled "+ Task.CurrentId);
        }
    }

enter image description here

我还使用 Parallel 并初始化 Cancellation Token Inside 方法 Do(),并使用 Timer 在时间跨度后取消令牌,但都给出相同的结果。

那么,为什么会发生这种情况以及在一段时间后取消任务的正确方法是什么???


通过使用相同的计时,您可以获得与原始“中止”版本相同的结果。例如,这段代码:

static void Main()
{
    var clt = new CancellationTokenSource();
    clt.CancelAfter(1000);
    for (int i = 0; i < 10; i++)
    {
        Task.Run(() => Do(clt.Token));
    }
    Console.ReadLine();
}

private static void Do(CancellationToken cltToken)
{
    Console.WriteLine("Start " + Task.CurrentId);
    Thread.Sleep(2000);

    if (!cltToken.IsCancellationRequested)
    {
        Console.WriteLine("End " + Task.CurrentId);
    }
    else
    {
        Console.WriteLine("Cancelled "+ Task.CurrentId);
    }
}

会产生类似的东西:

Start 111
Start 112
Start 113
Start 114
Start 115
Start 116
Start 117
Start 118
Start 119
Start 120
Cancelled 111
Cancelled 112
Cancelled 118
Cancelled 116
Cancelled 114
Cancelled 113
Cancelled 117
Cancelled 115
Cancelled 119
Cancelled 120

Using a CancellationTokenSource是比中止线程更好的选择。Thread.Abort是一个坏主意,因为它在不提供适当的清理机制的情况下中止线程。使用令牌可以让您合作地以干净的方式处理取消。

至于为什么你的其他选项无法正常运行 - 你使用的时间有点太接近了。在调试器下运行时,这尤其是一个问题,因为它会阻止计时(即:CancelAfterThread.Sleep)同时射击。如果您在 Visual Studio 主机进程之外运行发布版本,您可能会发现它们的工作更加可靠。

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

按时间取消任务 的相关文章

  • 必须打开存储才能执行此操作 - System.IO.Packaging.Package

    我正在使用 System IO Packaing Package 类来压缩文件 我的应用程序的多个实例可以同时运行 并读取和保存文件 当处理小文件时 一切似乎都很好 但是当涉及大文件时 如果应用程序的两个实例同时保存 我会收到一个异常 消息
  • 检查列表是否包含另一个列表。 C#

    编辑 只是说 ContainsAllItem 中的注释解释得最好 很抱歉问这个问题 我知道以前有人问过这个问题 但我只是不明白 好的 所以我想检查一个列表是否包含另一个列表中的所有项目WITHOUT重叠 以及根据类字符串 名称变量 称为项目
  • C# 中的协变和逆变

    首先我要说的是 我是一名正在学习 C 编程的 Java 开发人员 因此 我会将我所知道的与我正在学习的进行比较 我已经使用 C 泛型几个小时了 我已经能够在 C 中重现我在 Java 中知道的相同内容 除了几个使用协变和逆变的示例 我正在读
  • 使用 AJAX 或多线程加速页面加载

    我的页面有 5 个部分 每个部分大约需要 1 秒来渲染 Page Load RenderSection1 1 sec RenderSection2 1 sec RenderSection3 1 sec RenderSection4 1 se
  • 关闭 XDOCUMENT 的实例

    我收到这个错误 该进程无法访问文件 C test Person xml 因为它是 被另一个进程使用 IOException 未处理 保存文件内容后如何关闭 xml 文件的实例 using System using System Collec
  • 如何使用汇编获取BIOS时间?

    我正在从头开始实现一个小型操作系统 用于教育目的 现在 我想使用汇编来获取 BIOS 时间 我对此进行了很多搜索 但找不到任何代码示例来执行此操作 如果有人可以提供任何参考或代码示例或与此相关的任何内容 我将非常感激 See 时钟中断 1a
  • 通过引用传递时取消引用指针

    当通过引用传递给函数时取消引用指针时会发生什么 这是一个简单的例子 int returnSame int example return example int main int inum 3 int pinum inum std cout
  • 如何在 Windows 窗体中运行屏幕保护程序作为其背景?

    如何在 Windows 窗体中运行屏幕保护程序作为其背景 用户还可以在屏幕保护程序运行时与表单控件进行交互 为什么这个 我们有一个案例 需要在用户时运行 Windows Bubbles 屏幕保护程序 可以继续与表单控件交互吗 您可以使用以下
  • 将成员函数作为参数传递/c++

    我想用 C 实现一个类b可以通过封装该迭代器类型的成员集进行某种迭代 喜欢 b object for each x do function f so 函数 f会得到每个人的x成员并做任何事情 比方说 void function f x me
  • .net Framework (.net 4.0) 中定义 Base 3 数字的类

    我正在寻找一些可以用来定义 3 基数 三进制数 的类 有什么我可以在 net 框架中使用的东西或者我需要写一些东西吗 谢谢你的帮助 您可以使用解析Convert ToInt32 s base http msdn microsoft com
  • c# 如何生成锦标赛括号 HTML 表

    所以我已经被这个问题困扰了三个星期 但我一生都无法弄清楚 我想做的是使用表格获得这种输出 演示 http www esl world net masters season6 hanover sc2 playoffs rankings htt
  • 更改其他页面的主窗口内容

    在 WPF 应用程序的主窗口中 我有一个 Badged 元素 来自材料设计 这是我的代码
  • 从包含大量文件的目录中检索文件

    我的目录包含近 14 000 000 个 wav 格式的音频样本 所有普通存储 没有子目录 我想循环浏览文件 但是当我使用DirectoryInfo GetFiles 在该文件夹上 整个应用程序冻结了几分钟 可以用另一种方式完成吗 也许读取
  • 如何将字符串转换为 Indian Money 格式?

    我正在尝试将字符串转换为印度货币格式 例如如果输入为 1234567 则输出应为 12 34 567 我编写了以下代码 但它没有给出预期的输出 CultureInfo hindi new CultureInfo hi IN string t
  • `cosf`、`sinf` 等不在 `std` 中 [重复]

    这个问题在这里已经有答案了 根据这里的讨论 我有报告了一个错误 https bugs launchpad net ubuntu source gcc 8 bug 1831385给 Ubuntu 开发者 编译以下示例 C 程序时 includ
  • Dynamics Crm:获取状态代码/状态代码映射的元数据

    在 Dynamics CRM 2011 中 在事件实体上 状态原因 选项集 也称为状态代码 与 状态 选项集 也称为状态代码 相关 例如看这个截图 当我使用 API 检索状态原因选项集时 如下所示 RetrieveAttributeRequ
  • 将 bignum 类型结构转换为人类可读字符串的有效方法是什么?

    我有一点问题 为了增长我的 C 知识 我决定尝试实现一个基本的 bigint 库 bigint 结构的核心将是一个 32 位整数数组 选择它们是因为它们适合寄存器 这将允许我在数字之间进行操作 这些操作将在 64 位整数中溢出 这也将适合寄
  • 如何将 CSV 文件读入 .NET 数据表

    如何将 CSV 文件加载到System Data DataTable 根据CSV文件创建数据表 常规 ADO net 功能是否允许这样做 我一直在使用OleDb提供者 但是 如果您正在读取具有数值的行 但希望将它们视为文本 则会出现问题 但
  • 创建带有部分的选项卡式侧边栏 WPF

    我正在尝试创建一个带有部分的选项卡式侧边栏 如 WPF 中的以下内容 我考虑过几种方法 但是有没有更简单 更优雅的方法呢 方法一 列表框 Using a ListBox并将 SelectedItem 绑定到右侧内容控件所绑定的值 为了区分标
  • 使用剪贴板 SetText 换行

    如何使用 SetText 方法添加换行符 I tried Clipboard SetText eee n xxxx 但当我将剪贴板数据粘贴到记事本中时 它没有给我预期的结果 预期结果 eee xxxx 我怎样才能做到这一点 Windows

随机推荐

  • 从 android 将 JSONArray 发布到 WCF 服务

    我在将 JSONArray 值发布到我的 WCF 服务时遇到问题 当我从 Fiddler 或 Net Test Client 发布数据时 它工作正常 每次我尝试从我的 Android 应用程序发布时 我都会收到请求错误 这是我从 Andro
  • 如何在 MySQL 中正确使用 CASE..WHEN

    这是一个演示查询 注意它非常简单 仅在 base price 为 0 的情况下获取 但它仍然选择条件 3 SELECT CASE course enrollment settings base price WHEN course enrol
  • 如何在共享主机上安装 Composer?

    我有这些东西 文件http api odtu lu composer phar http api odtu lu phpinfo php FTP 访问 cPanel FreeBSD 上的 Cron 作业 PHP Perl CGI BIN P
  • Python 相当于 Ruby 的 .select

    我有一个列表 数组 我们称之为x 我想创建一个新的列表 数组 我们称之为这个z 从元素中x符合某种条件 在 Ruby 中 您可以通过调用列表 数组上的 select 方法来做到这一点 如下所示 x 1 2 3 4 5 6 7 8 9 10
  • 延迟加载单例:双重检查锁定与按需初始化持有者习惯用法

    我需要在并发环境中延迟加载资源 加载资源的代码应该只执行一次 Both 双重检查锁定 使用 JRE 5 和 volatile 关键字 和按需初始化持有者习惯用法似乎很适合这份工作 仅通过查看代码 按需初始化持有者习惯用法似乎更干净 更高效
  • Android onTouch 与 onClick 和 onLongClick

    我有一个自定义视图 其作用类似于按钮 我想在用户按下它时更改背景 当用户将手指移到外面或释放它时将背景恢复为原始状态 我还想处理 onClick onLongClick 事件 问题是 onTouch 要求我返回 trueACTION DOW
  • asp.net 5 mvc 6 loginUrl更改路径

    在 VS 2015 WebApplication 中创建新项目时 如果未授权 您将如何更改重定向登录 URL 路径 我创建了一个新区域 在其中创建了一个登录控制器 此登录控制器要求您获得授权 但是当尝试访问这些页面时 我被重定向到 Acco
  • UIViewContentMode模式指的是什么类型的内容?

    根据 UIView 的官方文档contentMode财产 The content mode specifies how the cached bitmap of the view s layer is adjusted when the v
  • 将操作栏更改为从 Fragment 内覆盖

    我有一个片段 片段 1 它被另一个片段 片段 2 替换 片段 1 被放置在堆栈上 我正在使用兼容模式 不是 ActionBarSherlock 这是我的问题 我希望操作栏在某些片段中显示为叠加 但在其他片段中则不然 具体来说 当显示片段 2
  • Ruby:在结构体中定义常量的语法

    考虑以下 正确的 Ruby 程序 class Outer Inner Struct new dummy do CONST abce def fun puts dummy end end end obj Outer Inner new 15
  • 最难逆向的 JavaScript 混淆器 [重复]

    这个问题在这里已经有答案了 我正在寻找目前最难逆向的 JavaScript 混淆器 如果它可以在自己的服务器上运行 则会加分 性能下降和代码膨胀都很好 用 Java 编写 然后使用混淆后的 JavaScript 运行字节码orto 这需要两
  • 如何将 Enum 的成员放入全局命名空间?

    Python 现在有一个 Enum 类型 3 4 中新增 与 PEP 435 还有向后移植 虽然命名空间是一件好事 但有时枚举更像常量 并且枚举成员应该位于全局 呃 模块 命名空间中 所以而不是 Constant Enum PI 3 14
  • JavaMail 与 MS Exchange:服务器和客户端均不支持身份验证机制

    我已经尝试从 Grails 应用程序发送邮件好几天了 但没有成功 我在用着 圣杯 1 3 7 邮件1 0插件 spring security core 1 2 6 插件 雄猫7 0 23 具体来说 我尝试从 Tomcat 服务器上部署的应用
  • 如何使用Vuejs在html中显示mysql blob图像?

    我有一个这样的 vue 文件 export default data return info name image errors created function this getInfo methods getInfo function
  • 应用程序 yml 属性的 Spring SpEL 表达式求值

    我正在尝试使用 Spring SpEL 表达式派生 application yml 配置文件中的属性值 但看起来该表达式没有被评估 这是我的 application yml 片段 spring profiles local cloud cl
  • Python 2.7 & ANTLR4:使 ANTLR 在无效输入时抛出异常

    我想捕获像这样的错误 line 1 1 extraneous input r n expecting line 1 1 mismatched input Vaasje expecting Tafel 我尝试将我的函数包装在 try catc
  • RuntimeError:针对 API 版本 a 编译的模块,但此版本的 numpy 是 9

    Code import numpy as np import cv Console gt gt gt runfile Users isaiahnields spyder2 temp py wdir Users isaiahnields sp
  • 从 Android Wear 心率传感器读取底层颜色/灯光数据?

    我想读取 Android Wear 智能手表上的心率传感器数据 这文档看起来心率传感器只报告两件事 心率 每分钟心跳次数 准确度测量或错误代码 是否可以获取Android Wear心率传感器的底层数据 即红光量 或绿光或蓝光 在任何时间点
  • 使用data.table在每组数据后面插入一行NA

    我试图在每组数据之后添加一行 NAR 之前已经有人问过类似的问题 每组数据后插入一个空行 在这种情况下 接受的答案也可以正常工作 如下所示 group lt c a b b c c c d d d d xvalue lt c 16 25 y
  • 按时间取消任务

    我有一个多线程应用程序 我需要在一定时间后取消每个任务 即使在取消时 它们使用非托管资源 现在我使用以下代码 例如控制台应用程序 在实际应用中 延迟可能发生在非托管资源中 static void Main for int i 0 i lt