【问题标题】:Why doesn't Windows Service work properly with System.Timers.Timer or System.Windows.Forms.Timer为什么 Windows 服务不能与 System.Timers.Timer 或 System.Windows.Forms.Timer 一起正常工作
【发布时间】:2012-02-09 18:12:56
【问题描述】:

我最近遇到了编写 Windows 服务的挑战。我需要定期请求一个 URL 并检查它的可用性。为此,我决定在服务的OnStart 方法中初始化一个计时器,并在timer_Tick 事件中完成所有工作。

我的第一种方法是使用System.Windows.Forms.Timer 及其Tick 事件。我选择了它,因为我正在阅读教程。不知何故,我无法使服务工作。它安装并启动没有问题,但它不会触发事件(我将调试器附加到进程并看到它没有被触发)。我认为在 Windows 服务中使用 Forms 计时器可能不是一个好主意,所以我决定切换到 System.Timers.Timer 并利用它的 Elapsed 事件。这也不起作用。我在 Windows 窗体应用程序中尝试了上述两种方法,它们都有效。

经过一番挖掘,我找到了这个网站:http://weblogs.asp.net/sibrahim/archive/2004/01/13/58429.aspx,博主建议在该网站上使用另一个计时器:System.Threading.Timer。我第三次改变了方法,BOOM 它开始像魅力一样发挥作用。

我的问题是:为什么我不能使用 Windows 服务中的其他计时器?为什么很难找到有关它的信息?

【问题讨论】:

  • 我现在发现这篇文章比较了不同的 .NET 计时器。绝对值得一读:msdn.microsoft.com/en-us/magazine/cc164015.aspx
  • System.Threading.Timer 是唯一一个在 Windows Server 2008 R2 中为我工作的,虽然 Timers.Timer 在我的 Windows 7 laptop 中工作。

标签: .net windows-services timer


【解决方案1】:

System.Windows.Forms.Timer 计时器使用 UI 的消息泵来编组滴答事件,默认情况下服务不会运行消息泵,因此如果没有一点额外的工作,System.Windows.Forms.Timer 计时器将无法工作。

System.Timers.Timer 是一个基于服务器的计时器,它会在您创建它的线程上引发一个事件(我认为)。如果这不起作用,则可能是您没有启动计时器,或者计时器在立即结束的线程上运行(例如,没有任何东西使线程保持活动状态,因此它完成了)。

http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx

System.Threading.Timer 计时器使用在ThreadPool 线程上运行的回调,并且根本不与消息泵相关联,因此这是有效的。

当您在 WinForms 项目中运行 Application.Run(myForm) 时,该调用还会启动消息泵,它管理 UI 消息。您提到的 windows 计时器是一个 UI 组件,并期望消息泵正在运行,以便在 UI 线程上发生滴答事件。

查看此处以在 Windows 服务中运行消息泵:

Message pump in .NET Windows service

进一步阅读:

http://support.microsoft.com/kb/842793

总之,我会选择System.Threading.Timer 类。

【讨论】:

  • 这两个计时器都在线程池线程上运行代码。让事件/回调在创建计时器的同一线程上运行需要魔法。消息泵提供的那种魔法。
【解决方案2】:

【讨论】:

  • 如果有重复,您可以用它标记问题本身。
猜你喜欢
  • 2021-08-18
  • 2021-12-06
  • 2020-09-01
  • 2021-12-15
  • 2011-10-05
  • 1970-01-01
  • 1970-01-01
  • 2017-03-16
  • 2023-03-07
相关资源
最近更新 更多