[英]can I write a C# program that - when run as a scheduled task - detects when Task Scheduler tries to stop it
也許我誤解了Windows的任務計划用戶界面的這一部分,但是以下選項建議 (對我來說)程序首先被要求很好地停止,然后在失敗時強行退出:
從我心中最深處的角落來看,我記得Windows應用程序可以響應退出的請求; 考慮到這一點,我能夠谷歌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!");
}
}
}
文藝青年最愛的我的問題是:
[edit]在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!” 但不是“再見!”
處理這個問題的正確方法是假設您的程序突然死亡而沒有任何機會運行代碼(因為,你知道,它可以 - 假設.NET運行時有一個觸發崩潰的錯誤)並在外面檢測到該程序,所以你可以從那里進行郵件/日志記錄。 如果您可以延遲,您仍然可以從程序本身執行此操作:在下一個任務運行時檢測到不干凈的關閉,然后通知。 這比在進程停止時(無論出於何種原因)嘗試進行清理/信令更可靠。 對於控制台應用程序(如果你正在使用它們)尤其如此,因為退出通常甚至不運行任何終結器 ,除非你為它編寫代碼( AppDomain.ProcessExit
和Console.CancelKeyPress
是不夠的,你必須去一直到SetConsoleCtrlHandler
)。 總而言之,這並沒有讓我對應用程序本身沒有執行的干凈退出抱有太多希望。
這不能回答原始問題,即您是否可以檢測到任務計划程序發出的停止請求,如果是,則如何檢測。 我試圖確定它是如何工作的,但是我失敗了:如果我在任務計划程序下運行一個拒絕退出的控制台應用程序,它會很快繼續運行,即使我已將其配置為在10秒或1秒后終止分鍾。 (你不能在接口上設置這么短的時間,但你可以從命令行。)我沒有測試Task Scheduler支持的最短時間,1小時是否有效。 我還沒有測試使用實際計划時的情況是否有所不同,而不是手動觸發的任務。 但是,如果你手動結束一個任務,它肯定只是調用TerminateProcess
並且沒有給你任何干凈退出的機會 - 僅此一點應該是一些動機,不要把你的代碼用於任務本身的信號失敗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.