保证代码在进程终止时执行

22

我需要在进程停止时(自动、用户、任务管理器等)执行一部分代码(状态保存)。

这是否可能?

try {} finally {}AppDomain.ProcessExitIDisposable、析构函数,下一步该尝试什么?


14
一个进程被非正常地终止的意义在于它会立刻停止正在进行的操作。我无法想到其他合适的方法来解决这个问题。 - Stefan H
斯蒂芬所说的; 这正是为什么强制杀死进程是一个坏主意的原因...进程无法恢复。 - Andrew Barber
1
仍然正确。你的答案完全不同...你总是可以保存状态以进行恢复,而且有许多方法可以实现。但这并不改变一个进程在被杀死后无法自行执行任何操作的事实。 - Andrew Barber
@Stefan:请将其发布为答案。 - abatishchev
7
这个前提是错误的。让你的应用程序能够抵御有人绊倒电源线的情况。这样就自动解决了其他所有问题。 - Hans Passant
4个回答

19

正如其他人所指出的,当应用程序被操作系统或用户“杀死”时,你无法在应用程序中执行任何代码。这就是为什么它被称为“Killing”的原因。

如果保存状态是你的应用程序的重要部分,你应该采取类似于数据库系统的方法。实现“事务日志”,创建“检查点”等。这是你能够接近的最近的方法。

在这种情况下,当你的应用程序恢复(在被“杀死”后重新运行)时,它可以检查这些“事务日志”以获取任何未完成的更新或最后状态更改。

除此之外,这真的取决于你想做什么。还有你为什么想到这个想法?我们能否获得更多细节?也许这里有更好的替代方案。


1
从一开始,我的想法似乎就是错误的,两个方面都是如此。我想将状态保存到我读取它的同一个位置 - App.config。但我无法保证代码执行或写入自定义部分(异常:配置文件已被另一个程序更改)。第二个问题更严重。因此,我认为我需要放弃第一个并重新制定第二个计划。 - abatishchev
2
注意“被杀死”和只是被请求停止之间的区别,以获得+1。 - Andrew Barber
1
是的,有时候用户会变得非常残忍(因为某些间谍软件而感到沮丧)。然后使用“任务管理器”进行“屠杀”(试图找出哪一个是间谍软件)... :) - decyclone

11

进程被非正常终止的整个意义在于它会突然停止正在进行的操作。我无法想到任何避免这种情况的方法。


3
我正在寻找一种与发布的原因略有不同的解决方案,但我为自己想出了一个非常好的解决方案,并且在这里进行说明可能会很有用:
注意:对于那些知道它是什么的人,这本质上是“心跳”设计模式。
1)除了运行将“死亡”(即被杀死)的代码之外,还要添加代码到该项目中,使其在初始化时生成一个线程(或可能是另一种方法?),并且所有线程所做的就是运行永远不会结束的while循环(但确保它在迭代之间至少睡眠几秒钟甚至1分钟),并且在while循环中记录指示器以指示您的应用程序“存活”(即“心跳”)。我个人建议在数据库或者文件中设置一个值,该值为当前时间戳(即DateTime.Now)。
2)现在您正在记录“心跳”,请创建另一个应用程序(即另一个进程),该应用程序除了读取“心跳”值(即当前时间戳)之外什么也不做,并且在永不结束的while循环中执行此操作。一旦确定“心跳”值是“错误”的(例如,如果HeartBeatTimestamp + 5分钟< DateTime.Now),则可以运行您希望在“进程被杀死后”运行的代码。
希望这可以帮助您:)如果您想了解更多信息,请随时从其他资源中研究“心跳”设计模式!
问候,
杰夫

3

你需要思考为什么程序会退出。如果是由于错误引起的,那么可以使用try/catch。在unix术语中,当进程管理器停止进程时,会发出一个kill命令(即发送SIGKILL信号),在进程退出之前不允许程序执行任何操作。许多病毒所做的是有两个进程(可能具有共享内存以避免常量数据同步),每个进程监视另一个进程的状态,当一个进程关闭时,另一个进程重新启动它。也许第二个进程可以以类似的方式监视和保存状态来处理你的情况。然而,另一种信号是SIGTERM。当您告诉计算机重新启动但有正在运行的进程时,将发送此信号。内核允许程序尝试自己退出,但最终会询问用户是否可以杀死该程序。如果要处理SIGTERM,请查找处理信号。最终,我知道的解决SIGKILL的唯一方法是使用两个进程的方案。


你的回答可能在某种程度上有助于 OP,但是将状态保存在某个地方(包括另一个进程中)并不能使进程在被操作系统“杀死”后继续执行代码。 - Andrew Barber
如果是SIGTERM,那个进程可以做一些事情。 - chacham15
7
你读到问题了吗?他在问一个进程被“终止”,并特别提到了“任务管理器”。 - Andrew Barber
3
使用看门狗似乎是一个有效的想法。是的,这并不完全是原帖所问的,但它可能会给他提供另一个想法。没有必要无礼。 - VitalyB
OP询问了有关停止进程的各种方式:“自动停止、用户停止、任务管理器停止等”。此外,在计算机科学中,术语经常会引起混淆。例如,当Windows进行重新启动时,您可能会说程序被终止了,但实际上它首先收到了sigterm信号,然后才被真正终止(使用sigkill)。 - chacham15

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接