You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何拦截Windows Task Scheduler终止信号,优雅停止其启动的控制台程序

任务计划程序终止信号逻辑

首先明确你提到的配置对应的系统行为:

  • 当任务达到运行时长阈值时,任务计划程序首先会向控制台进程发送CTRL_C_EVENT信号,等待进程自行退出
  • 默认等待时长为3分钟,若3分钟后进程仍在运行,才会调用TerminateProcess强制杀死进程(也就是你提到的第二个勾选项对应的逻辑)
信号捕获实现方案

根据你使用的开发语言,参考对应实现:

C# 实现

注册Console.CancelKeyPress事件拦截停止信号,配合关键区标记实现延迟退出:

// 全局标记:是否处于关键执行区域
private static volatile bool _inCriticalSection = false;
// 全局标记:是否收到终止请求
private static volatile bool _exitRequested = false;

static void Main(string[] args)
{
    // 注册CTRL+C信号处理
    Console.CancelKeyPress += (sender, e) =>
    {
        // 标记收到退出请求
        _exitRequested = true;
        // 取消默认的终止行为,给进程时间处理一致性逻辑
        e.Cancel = true;
        
        // 等待关键区执行完成
        while (_inCriticalSection)
        {
            Thread.Sleep(100);
        }
        
        // 此处执行DB一致性处理、资源释放逻辑
        FlushDbTransactions();
        CleanupResources();
        
        // 主动退出
        Environment.Exit(0);
    };
    
    // 业务逻辑执行
    while (true)
    {
        if (_exitRequested) break;
        
        try
        {
            _inCriticalSection = true;
            // 此处执行你的关键DB操作
            ExecuteCriticalDbWork();
        }
        finally
        {
            _inCriticalSection = false;
        }
        
        // 非关键区逻辑
        ExecuteNonCriticalWork();
    }
}

C/C++ 实现

通过SetConsoleCtrlHandler注册控制信号处理函数:

#include <windows.h>
#include <stdbool.h>

volatile bool inCriticalSection = false;
volatile bool exitRequested = false;

BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType)
{
    if (dwCtrlType == CTRL_C_EVENT)
    {
        exitRequested = true;
        // 等待关键区执行完成
        while (inCriticalSection)
        {
            Sleep(100);
        }
        // 执行一致性处理、资源释放
        FlushDbTransactions();
        CleanupResources();
        ExitProcess(0);
        return TRUE;
    }
    return FALSE;
}

int main()
{
    // 注册控制信号处理函数
    SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
    
    while (1)
    {
        if (exitRequested) break;
        
        __try
        {
            inCriticalSection = true;
            ExecuteCriticalDbWork();
        }
        __finally
        {
            inCriticalSection = false;
        }
        
        ExecuteNonCriticalWork();
    }
    return 0;
}
注意事项
  • 一致性处理逻辑总耗时不要超过3分钟,否则任务计划程序仍会强制杀死进程,建议将一致性操作设计为轻量化逻辑
  • 标记关键区状态的变量需要加volatile修饰,避免编译器优化导致信号处理线程读取到过期值
  • 不要在信号处理函数中执行耗时过长、可能阻塞的操作,避免触发系统强杀

内容的提问来源于stack exchange,提问作者Skary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 15:06:04