我有一个windows服务应用程序。并调试它运行在控制台模式。
这里http://support.microsoft.com/kb/842793写的是Timers.Timer有一个bug,在windows服务中不触发。解决方法是使用Threading.Timer。本文是针对.NET 1.0和1.1的
我使用的是.NET 4,但是过了一段时间线程。计时器也没有启动。那么这是什么原因呢?你有什么建议作为一个变通方案?
我有一个windows服务应用程序。并调试它运行在控制台模式。
这里http://support.microsoft.com/kb/842793写的是Timers.Timer有一个bug,在windows服务中不触发。解决方法是使用Threading.Timer。本文是针对.NET 1.0和1.1的
我使用的是.NET 4,但是过了一段时间线程。计时器也没有启动。那么这是什么原因呢?你有什么建议作为一个变通方案?
6条答案
按热度按时间1rhkuytd1#
您是否在某个地方保留了对计时器的引用,以防止它被垃圾收集?
从the docs开始:
只要您在使用Timer,就必须保留对它的引用。与任何托管对象一样,当没有对Timer的引用时,Timer会受到垃圾回收的影响。Timer仍处于活动状态这一事实并不妨碍它被回收。
siv3szwd2#
计时器对象超出范围,并在一段时间后被垃圾收集器擦除,这会阻止回调的触发。
将对它的引用保存在类的成员中。
b1zrtrql3#
变通一下?
个人而言,我建议使用RegisterWaitForSingleObject函数,而不是计时器,这是你遇到的确切原因。RegisterWaitForSingleObject注册了一个委托,在你设置的类似计时器的时间间隔内调用,而且 * 超级 * 容易实现。你可以在几个小时内启动并运行一个测试工具。我在我的Windows服务中使用这种间隔触发方法,这是一个久经考验的、真正稳定的解决方案,对我很有效。
阅读下面的链接,然后转到文章中的链接以获取代码示例和演练。
http://allen-conway-dotnet.blogspot.com/2009/12/running-periodic-process-in-net-using.html
bakd9h0s4#
以下是使用RegisterWaitForSingleObject的方法:
当您有代码注册一个计时器时,如下所示:
你可以拥有这个:
您可以在ServiceBusTimerCallback之后使用allTasksWaitHandle.Set()通知用户任务已完成,因此它将立即再次运行任务。上面发布的此代码将在timeont过去后运行任务,即每20秒运行一次。
我在WebAPI项目中实现了它,效果很好。
tvmytwxo5#
使用企业库进行日志记录和循环线程的windows服务的完整示例。如果不使用企业库,请删除logger.write行
2q5ifsrm6#
下面是一个实验性的演示,说明一个非根
System.Threading.Timer
可以进行垃圾回收。仅仅因为它被安排在将来执行,并不能阻止它被回收。输出:
Online demo.