windows-services - Windows 服务与计划任务

标签 windows-services scheduled-tasks

Windows 服务与重复运行程序(例如每两分钟)的计划任务相比有何优缺点?

最佳答案

更新:

距离我原来的答案已经过去近四年了,这个答案已经非常过时了。自 TopShelf Windows 服务的开发变得很容易。现在您只需要弄清楚如何支持故障转移...

原答案:

我真的不喜欢 Windows Scheduler。用户的密码必须提供为 @moodforall上面指出,当有人更改该用户的密码时,这很有趣。

Windows Scheduler 的另一个主要烦恼是它以交互方式运行,而不是作为后台进程运行。当 RDP session 期间每 20 分钟弹出 15 个 MS-DOS 窗口时,您会后悔没有将它们安装为 Windows 服务。

无论您选择什么,我当然建议您将处理代码从控制台应用程序或 Windows 服务中分离到不同的组件中。然后您可以选择从控制台应用程序调用工作进程并将其挂接到 Windows Scheduler,或者使用 Windows 服务。

您会发现安排 Windows 服务并不有趣。一个相当常见的场景是,您有一个长时间运行的进程,并且希望定期运行。但是,如果您正在处理队列,那么您确实不希望同一工作线程的两个实例处理同一队列。因此,您需要管理计时器,以确保长时间运行的进程运行时间超过指定的计时器间隔,在现有进程完成之前它不会再次启动。

写完所有这些后,您会想,为什么我不直接使用 Thread.Sleep?这允许我让当前线程继续运行直到完成,然后暂停间隔开始,线程进入休眠状态并在所需时间后再次启动。整洁!

然后你阅读了互联网上的所有建议,很多专家告诉你这是非常糟糕的编程实践:

http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx

所以你会摸不着头脑,心里想,WTF,撤消待结账 -> 是的,我确定 -> 撤消今天所有的工作......该死,该死,该死......

但是,我确实喜欢这种模式,即使每个人都认为它很糟糕:

OnStart method for the single-thread approach.

protected override void OnStart (string args) {

   // Create worker thread; this will invoke the WorkerFunction
   // when we start it.
   // Since we use a separate worker thread, the main service
   // thread will return quickly, telling Windows that service has started
   ThreadStart st = new ThreadStart(WorkerFunction);
   workerThread = new Thread(st);

   // set flag to indicate worker thread is active
   serviceStarted = true;

   // start the thread
   workerThread.Start();
}

The code instantiates a separate thread and attaches our worker function to it. Then it starts the thread and lets the OnStart event complete, so that Windows doesn't think the service is hung.

Worker method for the single-thread approach.

/// <summary>
/// This function will do all the work
/// Once it is done with its tasks, it will be suspended for some time;
/// it will continue to repeat this until the service is stopped
/// </summary>
private void WorkerFunction() {

   // start an endless loop; loop will abort only when "serviceStarted"
   // flag = false
   while (serviceStarted) {

      // do something
      // exception handling omitted here for simplicity
      EventLog.WriteEntry("Service working",
         System.Diagnostics.EventLogEntryType.Information);

      // yield
      if (serviceStarted) {
         Thread.Sleep(new TimeSpan(0, interval, 0));
      }
   }

   // time to end the thread
   Thread.CurrentThread.Abort();
}

OnStop method for the single-thread approach.

protected override void OnStop() {

   // flag to tell the worker process to stop
   serviceStarted = false;

   // give it a little time to finish any pending work
   workerThread.Join(new TimeSpan(0,2,0));
}

来源:http://tutorials.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1%3a_Use_a_Separate_Thread (无效链接)

多年来我一直在运行大量这样的 Windows 服务,它对我很有效。我还没有看到人们同意的推荐模式。只做对你有用的事情。

关于windows-services - Windows 服务与计划任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/390307/

相关文章:

windows-services - 如何以编程方式停止Windows Service?

跨 IPC 的 C# 事件

c# - 为 schtasks.exe 指定日期参数的语言独立方式

swift - 定期运行 Swift 脚本

java - 使用类字段中的 cron 表达式安排作业

python - 设置计划的工作?

c# - WCF:在 IIS 和 WIndows 服务中托管的区别

multithreading - 我怎样才能完成ThreadPool.Join?

c# - 开发人员是否可以通过 "force"系统来防止 "Metro"应用程序在后台异步进程运行时被挂起?

windows - 如何解决 Windows 计划任务未运行的问题?