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

控制台退出事件仅持续5秒,如何确保清理函数执行完成?

解决方案:突破控制台关闭时5秒的清理时间限制

Windows系统对控制台进程的SetConsoleCtrlHandler回调函数默认设置了5秒超时,超时后会强制终止进程。要确保清理操作有足够时间完成,可通过以下方式解决:

核心思路

当收到控制台关闭信号时,让回调函数返回true,告知系统我们将自行处理退出逻辑,这样系统就不会触发5秒后的强制终止。随后通过退出标志让主循环结束,在主流程中执行完整的清理操作。

修改后的代码

using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace ConsoleApp1
{
    public class Test
    {
        [DllImport("Kernel32")]
        private static extern bool SetConsoleCtrlHandler(SetConsoleCtrlEventHandler handler, bool add);

        private delegate bool SetConsoleCtrlEventHandler(CtrlType sig);

        private enum CtrlType
        {
            CTRL_C_EVENT = 0,
            CTRL_BREAK_EVENT = 1,
            CTRL_CLOSE_EVENT = 2,
            CTRL_LOGOFF_EVENT = 5,
            CTRL_SHUTDOWN_EVENT = 6
        }

        // 退出标志,用于通知主循环终止
        private static bool _isExiting = false;

        private static bool Handler(CtrlType signal)
        {
            switch (signal)
            {
                case CtrlType.CTRL_BREAK_EVENT:
                case CtrlType.CTRL_C_EVENT:
                case CtrlType.CTRL_LOGOFF_EVENT:
                case CtrlType.CTRL_SHUTDOWN_EVENT:
                case CtrlType.CTRL_CLOSE_EVENT:
                    Console.WriteLine("开始执行清理操作...");
                    _isExiting = true;
                    // 返回true,告诉系统我们自行处理退出,避免5秒强制终止
                    return true;

                default:
                    return false;
            }
        }

        public static void Main(string[] args)
        {
            // 注册控制台信号处理器
            SetConsoleCtrlHandler(Handler, true);

            // 主业务循环
            while (!_isExiting)
            {
                Thread.Sleep(50);
                // 这里可以添加你的业务逻辑
            }

            // 执行清理操作,这里有足够时间完成所有任务
            Console.WriteLine("正在清理资源...");
            // 示例:模拟耗时的清理操作
            Thread.Sleep(10000); // 10秒的清理任务
            Console.WriteLine("清理完成,进程即将退出");
            Environment.Exit(0);
        }
    }
}

关键说明

  • 返回true的作用:回调函数返回true会阻止系统执行默认的终止流程,取消5秒倒计时强制关闭的逻辑。
  • 退出标志的使用:通过_isExiting标志让主循环优雅退出,将清理操作放在主流程中执行,避免在信号回调线程中执行过长任务(信号回调线程属于系统线程,长时间占用可能引发其他问题)。
  • 特殊场景处理:如果是处理系统注销/关机信号(CTRL_LOGOFF_EVENT、CTRL_SHUTDOWN_EVENT),系统最终仍会强制终止进程,但此时的超时时间会比5秒更长,足以完成大部分常规清理任务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 09:51:20