【问题标题】:Guarantee code execution even on process kill即使在进程终止时也能保证代码执行
【发布时间】:2011-05-27 15:41:54
【问题描述】:

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

有可能吗?

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

【问题讨论】:

  • 一个进程被不优雅地杀死的全部意义在于它只是停止了它正在做的事情。我真的找不到解决办法。
  • 斯蒂芬说了什么;这就是为什么杀死这样的进程是一个坏主意的原因......进程恢复是不可能的。
  • 仍然如此。你的答案完全是另外一回事......你总是可以保存状态来恢复,并且有很多方法可以做到这一点。但这并不能改变进程在被杀死后不能做任何事情的事实。
  • @Stefan:请作为答案发帖
  • 这是错误的前提。使您的应用程序能够抵御被电源线绊倒的人。其他所有内容也会自动覆盖。

标签: c# .net process kill-process


【解决方案1】:

正如其他人所指出的,当应用程序中的任何代码是 KilledOperating SystemUser 时,您无法执行任何代码。这就是为什么它被称为Killing

如果保存状态是应用程序的重要组成部分,则应采用类似于数据库系统的方法。实现transaction log,创建checkpoints等。这是你能得到的最接近的。

在这种情况下,当您的应用程序恢复(在 killed 后重新运行)时,它可以检查这些 transaction logs 是否有任何待处理的更新或最后的状态更改。

除此之外,这实际上取决于您想做什么。还有你为什么想出这个主意?我们能得到更多细节吗?可能这里有人有更好的选择。

【讨论】:

  • 看来我的想法从一开始就错了,在这两点上。我想将状态保存到我阅读它的同一个地方——App.config。但我不能保证既不执行代码,也不保证写入自定义部分(例外:配置文件已被另一个程序更改)。第二个问题要严重得多。所以我认为我需要先放弃,然后再重新设计。
  • +1 表示关注 killed 和被要求停止之间的区别。
  • 是的,用户有时会变得非常残忍(被某些间谍软件挫败)。然后使用Task Manager 继续killing spree(试图找出哪个是间谍软件)... :)
【解决方案2】:

一个进程被不优雅地杀死的全部意义在于它只是停止了它正在做的事情。我真的想不出办法。

【讨论】:

    【解决方案3】:

    您需要考虑程序退出的原因。如果是因为错误,那么您可以使用 try/catch。在 unix 术语中,进程管理器停止进程时发生的事情是终止(即发送 SIGKILL 信号),它不允许程序在进程退出之前执行任何操作。许多病毒所做的是有两个进程(可能使用共享内存以避免持续的数据同步),每个进程都监视另一个进程的状态,当一个进程宕机时,另一个进程会重新启动它。也许第二个进程可以为您的案例以类似的方式监视和保存状态。不过,另一种信号是 SIGTERM。当您告诉计算机重新启动但有进程正在运行时,会发送此信号。内核允许程序自行尝试退出,但最终会询问用户是否可以终止程序。如果要处理 SIGTERM 查找处理信号。最终,我所知道的 SIGKILL 的唯一解决方案是两个进程的解决方案。

    【讨论】:

    • 您的回答可能会以某种方式帮助 OP,但在某处(包括在另一个进程中)保存状态并不能使进程自身执行代码之后 它已被操作系统杀死
    • 如果它是一个 sigterm,那么进程可以做一些事情
    • 你读过这个问题吗?他在询问一个进程被杀死,并特别提到了Task Manager
    • 在这里使用看门狗似乎是一个有效的想法。是的,这不是 OP 所要求的,但它可能会给他一个额外的想法。没必要粗鲁。
    • OP 询问可以停止进程的各种方式:“自行、用户、任务管理器等。”此外,术语在 CS 中经常被混淆。例如,您可能会说一个程序在 Windows 重新启动时被杀死,而实际上它在实际被杀死之前首先获得了一个 sigterm(使用 sigkill)。
    【解决方案4】:

    我环顾四周的原因与发布的内容有些不同,但我为自己想出了一个非常好的解决方案,在这里说明可能有用:

    注意:对于那些知道它是什么的人来说,这本质上是“心跳”设计模式。

    1) 除了会“死”(即被杀死)的代码之外,向该项目添加代码,使其在初始化时生成一个线程(或可能是其他方法?),并且所有线程都运行一个永无止境的 while 循环(但要确保它在迭代之间至少休眠几秒钟甚至 1 分钟)并在 while 循环中记录一个指示符以指示您的应用程序处于“活动状态”(即“心跳”)。我个人建议在数据库或文件中设置一个值,即当前时间戳(即 DateTime.Now)

    2) 现在您正在记录“心跳”,创建另一个应用程序(即另一个进程),它只读取心跳值(即当前时间戳)并在一个永无止境的 while 循环中执行此操作。一旦确定心跳值“坏”(例如,如果 HeartBeatTimestamp + 5 min

    希望这会有所帮助 :) 如果您想了解更多信息,请随时从其他资源中研究“心跳”设计模式!

    干杯,

    杰夫

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-11
      • 2020-06-03
      • 2021-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-04
      相关资源
      最近更新 更多