AppDomain.CurrentDomain.ProcessExit
。然而,似乎任务计划程序"停止任务......"和AppDomain.CurrentDomain.ProcessExit
没有按照我的希望一起工作;这是一个示例程序,我将不工作:放在一起
using System;
using System.Threading;
using System.Windows.Forms;
namespace GimmeJustASec
{
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.ProcessExit += new EventHandler(SuddenCleanup);
while(true)
{
Thread.Sleep(1000);
}
}
static void SuddenCleanup(object sender, EventArgs e)
{
MessageBox.Show("Hello!");
}
}
}
tl; dr 我的问题是:
[编辑]在Andrew Morton的请求中尝试了这个变体,结果类似:
using System;
using System.Threading;
using System.Windows.Forms;
using System.IO;
namespace GimmeJustASec
{
class Program
{
private static StreamWriter _log;
static void Main(string[] args)
{
_log = File.CreateText("GimmeJustASec.log");
_log.AutoFlush = true;
_log.WriteLine("Hello!");
AppDomain.CurrentDomain.ProcessExit += new EventHandler(SuddenCleanup);
while(true)
{
Thread.Sleep(1000);
}
}
static void SuddenCleanup(object sender, EventArgs e)
{
_log.WriteLine("Goodbye!");
}
}
}
任务计划程序停止任务后,.log文件包含" Hello!"但不是"再见!"
答案 0 :(得分:1)
处理这个问题的正确方法是假设你的程序突然死亡而没有任何机会运行代码(因为,你知道,它可以 - 让我们说.NET运行时有一个错误触发崩溃)并在程序外部检测到这一点,因此您可以从那里进行邮件发送/日志记录。如果您可以延迟,您仍然可以从程序本身执行此操作:在下一个任务运行时检测到不干净的关闭,然后通知。这比在进程停止时(无论出于何种原因)尝试进行清理/信令更可靠。对于控制台应用程序尤其如此(如果您正在使用这些应用程序),因为通常会doesn't even run any finalizers退出,除非您为其编写代码(AppDomain.ProcessExit
和Console.CancelKeyPress
并非如此够了,你得走all the way to SetConsoleCtrlHandler
)。总而言之,这并没有让我对应用程序本身没有执行的干净退出抱有太多希望。
这不能回答原始问题,即您是否可以检测到任务计划程序发出的停止请求,如果是,则如何检测。我试图确定它是如何工作的,但是我失败了:如果我在任务计划程序下运行一个拒绝退出的控制台应用程序,它会快乐地继续运行,即使我已将其配置为在之后终止10秒或1分钟。 (你不能从界面设置这么短的时间,但你可以从命令行。)我没有测试任务计划程序支持的最短时间,1小时是否有效。如果使用实际的时间表而不是手动触发的任务,事情也会有所不同,我也没有测试过。但是,如果你手动结束一项任务,它肯定只是调用TerminateProcess
并且没有给你任何干净退出的机会 - 仅此一点应该是一些动机,不要把你的代码用于信号失败。任务本身。