news 2026/7/15 4:27:58

win下,当.NET控制台进程被强制终止(如关闭控制台、任务管理器结束进程等)时,如何优雅地清理数据

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
win下,当.NET控制台进程被强制终止(如关闭控制台、任务管理器结束进程等)时,如何优雅地清理数据

win下,当.NET控制台进程被强制终止(如关闭控制台、任务管理器结束进程等)时,如何优雅地清理数据

在Windows下,当.NET控制台进程被强制终止时,优雅地清理数据是一个挑战。以下是几种处理方案,按推荐程度排序:

1.最佳方案:结合多种事件处理

usingSystem;usingSystem.Runtime.InteropServices;usingSystem.Threading;classProgram{// Windows API 定义[DllImport("Kernel32")]privatestaticexternboolSetConsoleCtrlHandler(EventHandlerhandler,booladd);privatedelegateboolEventHandler(CtrlTypesig);privatestaticEventHandler_handler;enumCtrlType{CTRL_C_EVENT=0,CTRL_BREAK_EVENT=1,CTRL_CLOSE_EVENT=2,CTRL_LOGOFF_EVENT=5,CTRL_SHUTDOWN_EVENT=6}privatestaticboolConsoleCtrlCheck(CtrlTypectrlType){Console.WriteLine($"接收到关闭信号:{ctrlType}");Cleanup();returntrue;// 返回true表示已处理}staticvoidMain(string[]args){// 注册控制台控制事件处理器_handler+=newEventHandler(ConsoleCtrlCheck);SetConsoleCtrlHandler(_handler,true);// 注册进程退出事件AppDomain.CurrentDomain.ProcessExit+=(s,e)=>Cleanup();// 注册AppDomain卸载事件AppDomain.CurrentDomain.DomainUnload+=(s,e)=>Cleanup();// 对于需要取消的循环操作,使用CancellationTokenvarcts=newCancellationTokenSource();Console.CancelKeyPress+=(sender,e)=>{Console.WriteLine("Ctrl+C 被按下");e.Cancel=true;// 防止立即退出cts.Cancel();Cleanup();};try{// 主程序逻辑RunApplication(cts.Token);}finally{// 正常退出时的清理Cleanup();}}staticvoidRunApplication(CancellationTokentoken){// 示例:使用CancellationToken来响应取消请求while(!token.IsCancellationRequested){Console.WriteLine("程序运行中... 按Ctrl+C退出");Thread.Sleep(1000);}}staticvoidCleanup(){// 使用标志避免重复清理if(_isCleaned)return;_isCleaned=true;try{Console.WriteLine("开始清理资源...");// 1. 保存数据到文件SaveCriticalData();// 2. 关闭数据库连接等资源CloseDatabaseConnections();// 3. 释放文件锁等ReleaseFileLocks();// 4. 记录日志LogShutdown();Console.WriteLine("清理完成");// 等待所有异步操作完成Thread.Sleep(500);// 给清理操作一点时间}catch(Exceptionex){Console.WriteLine($"清理过程中发生错误:{ex.Message}");}}privatestaticbool_isCleaned=false;// 示例清理方法staticvoidSaveCriticalData(){try{// 保存关键数据到文件File.WriteAllText("backup.txt",DateTime.Now.ToString());}catch{/* 忽略错误 */}}staticvoidCloseDatabaseConnections(){// 关闭数据库连接}staticvoidReleaseFileLocks(){// 释放文件锁}staticvoidLogShutdown(){// 记录关闭日志}}

2.备用方案:使用子进程监控

对于无法捕获的终止(如任务管理器强制结束),可以创建一个监控进程:

// 监控程序(父进程)classMonitorProgram{staticvoidMain(){varprocess=newProcess{StartInfo=newProcessStartInfo{FileName="YourConsoleApp.exe",UseShellExecute=false}};process.Start();// 监控子进程退出process.WaitForExit();// 子进程退出后执行清理if(process.ExitCode!=0){PerformEmergencyCleanup();}}staticvoidPerformEmergencyCleanup(){// 紧急清理逻辑}}

3.防御性编程策略

3.1 定期保存状态

classProgramWithAutoSave{privatestaticTimer_autoSaveTimer;privatestaticreadonlyobject_saveLock=newobject();staticvoidMain(){// 每隔5分钟自动保存_autoSaveTimer=newTimer(_=>{lock(_saveLock){SaveCurrentState();}},null,TimeSpan.Zero,TimeSpan.FromMinutes(5));// 主程序逻辑}staticvoidSaveCurrentState(){// 保存当前状态到临时文件vartempFile=$"autosave_{DateTime.Now:yyyyMMddHHmmss}.tmp";// ... 保存逻辑}}

3.2 使用文件锁确保数据一致性

classProgramWithFileLock{privatestaticFileStream_lockFile;staticvoidMain(){try{// 创建锁文件_lockFile=File.Open("app.lock",FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.None);// 程序主逻辑RunProgram();}finally{_lockFile?.Close();File.Delete("app.lock");}}staticvoidCheckForPreviousCrash(){if(File.Exists("app.lock")){// 上次程序异常退出RecoverFromCrash();}}}

4.Windows服务替代方案

如果可靠性要求很高,考虑使用Windows服务:

usingSystem.ServiceProcess;publicclassMyService:ServiceBase{protectedoverridevoidOnStart(string[]args){// 启动逻辑}protectedoverridevoidOnStop(){// 优雅停止Cleanup();}protectedoverridevoidOnShutdown(){// 系统关机时调用Cleanup();base.OnShutdown();}}

5.重要注意事项

  1. 清理时间限制:Windows在进程终止时只给大约30秒的时间进行清理
  2. 避免阻塞操作:清理操作应该快速完成
  3. 幂等性设计:清理操作应该可以安全地重复执行
  4. 关键数据立即持久化:重要数据应该立即写入磁盘,而不是缓存在内存中

推荐的最佳实践组合:

// 简化的最佳实践示例classRobustConsoleApp{staticvoidMain(){// 1. 设置控制台事件处理器SetConsoleHandlers();// 2. 检查上次是否异常退出CheckForCrashRecovery();// 3. 使用using确保资源释放using(varcriticalResource=newCriticalResource())using(varcts=newCancellationTokenSource()){// 4. 设置取消令牌Console.CancelKeyPress+=(s,e)=>{e.Cancel=true;cts.Cancel();};// 5. 主程序循环try{MainLoop(cts.Token);}finally{Cleanup();}}}}

重要提示:没有任何方法可以100%保证在强制终止时执行清理代码。最好的策略是:

  1. 设计应用程序使其可以容忍突然终止
  2. 定期保存状态到持久化存储
  3. 提供崩溃恢复机制
  4. 使用事务性操作保证数据一致性
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 9:41:39

AGV 无人叉车在物流搬运中的核心优势

在物流成本上升、安全要求趋严的背景下,无人叉车已成为内部物流自动化的核心装备,正彻底改变传统仓储和物料搬运的运作模式。 AiTEN海豚之星作为全球领先的无人叉车与内部物流自动化解决方案提供商,依托全产品矩阵、自研核心技术与成熟交付能…

作者头像 李华
网站建设 2026/7/14 1:53:58

你画我猜计时答题对战房间酒馆互动神器H5开源

让我为您介绍这个"云起SAAS小酒馆互动H5"系统。 系统介绍 这是一个云起SAAS小酒馆互动H5系统,一个完整的双人对战游戏平台。 核心功能 1. 双人游戏模式计时答题对战: 双方同步答题,统计得分和用时,得分高且用时短者胜,输方接受惩罚你画我猜对战: 一人画一人猜,画手完…

作者头像 李华
网站建设 2026/7/8 3:43:10

《计算机网络》深入学:组帧

在计算机网络的世界里,物理层像是一个不知疲倦的搬运工,它只负责传输比特流(0 和 1),却并不关心这些比特代表什么意义。 而数据链路层(Data Link Layer) 的核心任务之一,就是把这些…

作者头像 李华
网站建设 2026/7/4 20:07:19

大模型训练全流程实战指南(一)——为什么要学习大模型训练?

前言 2025年,大模型技术迈入了飞速发展的新阶段。自从DeepSeek-R1引入强化学习方法以来,模型的能力得到了系统性提升,整个领域的发展宛如“打通任督二脉”,进入了前所未有的快车道。无论是国外闭源模型——如OpenAI的GPT系列、An…

作者头像 李华
网站建设 2026/7/3 2:25:43

流式聚合不慢才怪?窗口、触发器和内存这三板斧你真用对了吗

流式聚合不慢才怪?窗口、触发器和内存这三板斧你真用对了吗做流处理这些年,我发现一个特别有意思的现象: 👉 大家都在写聚合,真正把“聚合性能”当回事的人并不多。 很多同学一上来就是: keyBywindowsum / …

作者头像 李华