gpt4 book ai didi

c# - 我可以编写一个 C# 程序吗 - 当作为计划任务运行时 - 检测 Task Scheduler 何时试图停止它

转载 作者:可可西里 更新时间:2023-11-01 13:46:14 27 4
gpt4 key购买 nike

也许我误解了 Windows 的任务计划程序 UI 的这一部分,但以下选项建议(对我来说)程序首先被很好地要求停止,然后在失败时强行退出:

if the running task does not end when requested...

从我脑海的最深处,我记得 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!");
}
}
}

tl;dr 我的问题是:

  1. 能否编写一个程序来响应任务计划程序的停止? (或者 Task Scheduler 是否以最粗鲁的方式强制退出任务?)
  2. 如果一个程序可以这样写,怎样才是正确的写法? (我尝试的方式显然不正确。)
  3. 我是不是想得太多了,让程序本身在并行线程中运行会更好吗? (可能在 app.config 中设置了最大时间,或其他。)

[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 运行时有一个 bug 会触发崩溃)并且在程序外检测到它,因此您可以从那里进行邮件/日志记录。如果您可以忍受延迟,您仍然可以从程序本身执行此操作:在任务下次运行时检测到不正常关闭,然后通知。这比在进程停止时(无论出于何种原因)尝试进行清理/发信号要可靠得多。对于控制台应用程序(如果您正在使用它们)尤其如此,因为通常会退出这些应用程序 doesn't even run any finalizers ,除非你为它编写代码(AppDomain.ProcessExitConsole.CancelKeyPress 是不够的,你必须去 all the way to SetConsoleCtrlHandler )。总而言之,这并没有让我对不是由应用程序本身执行的干净退出抱有太大希望。

这并没有回答最初的问题,即您是否可以检测到任务计划程序发出的停止请求,如果可以,如何检测。我试图确定它是如何工作的,但我失败了:如果我在拒绝退出的任务计划程序下运行一个控制台应用程序,它会愉快地继续运行,即使我已经将它配置为在 10 秒或 1 秒后终止分钟。 (您不能从界面设置这么短的超时,但可以从命令行设置。)我没有测试 Task Scheduler 支持的最短时间 1 小时是否有效。我也没有测试使用实际计划而不是手动触发的任务时情况是否有所不同。但是,如果您手动结束任务,它肯定只会调用 TerminateProcess 并且不会给您任何干净退出的机会——仅此一点就应该是不将用于发出失败信号的代码放入其中的动机任务本身。

关于c# - 我可以编写一个 C# 程序吗 - 当作为计划任务运行时 - 检测 Task Scheduler 何时试图停止它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45867873/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com