每20秒调用一个方法的最有效方法是什么?

16

我希望每20秒调用一次一个带有参数的方法,例如: public void ProcessPerson(IPerson person)

我已经阅读了不同的计时器选项,并想知道有没有人能推荐最有效的方法来实现这个目标?

此外,是否有一种方法可以保持参数的强类型,而不是使用 object 然后转换为 IPerson?

谢谢你的帮助。


我只是好奇,为什么你要每20秒处理一个人,而不是在收到每个人的瞬间就处理他们呢? - Juliet
1
这只是一个例子,可能有些拙劣 :), 我真正感兴趣的是如何每n秒调用一个带有强类型参数的方法。 - CiaraM
3个回答

22
你需要的是一个 System.Threading.Timer:

提供了一种按照指定时间间隔执行方法的机制。

使用 TimerCallback 委托来指定 Timer 执行的方法。当 Timer 构造函数被调用时,必须指定 Timer 委托,并且不能改变。该方法不会在创建 Timer 的线程上执行,而是在由系统提供的 ThreadPool 线程上执行。

还有一个 System.Windows.Forms.Timer:

实现了一个定时器,在用户定义的时间间隔内引发事件。此计时器经过优化,适用于 Windows Forms 应用程序,并且必须在窗口中使用。

这个 Windows 定时器是为单线程环境设计的,其中使用 UI 线程执行处理。

还有一个不要忘记 System.Timers.Timer:

Timer 组件是一个基于服务器的计时器,允许您在应用程序中指定重复间隔,以便在 Elapsed 事件中引发。

基于服务器的 Timer 是为多线程环境下的工作线程设计的。服务器计时器可以在线程之间移动以处理引发的 Elapsed 事件,从而比 Windows 计时器更准确地按时引发事件。

所以请仔细研究每个定时器,并决定哪一个最适合您的情况。


4
如果他使用Windows Forms,那么System.Windows.Forms.Timer是更好的选择,因为回调函数将在UI线程上执行。 - Petar Minchev
@Petar - 谢谢你,我已经更新了答案来涵盖两个方面。 - ChrisF
还有一个 System.Timers.Timer。为了完整起见,也许你可以把它加入到你的答案中? - Brian Gideon
其中,System.Windows.Forms.Timer 由于基于 WM_TIMER 消息,这是一条非常低优先级的消息,并且只有在消息队列中的所有其他消息都被处理完毕后才会被传递,因此其精度最低。 - Chris Taylor
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx 和 http://mark.michaelis.net/Blog/SystemWindowsFormsTimerVsSystemThreadingTimerVsSystemTimersTimer.aspx - SwDevMan81

3
我会选择System.Threading.Timer。请注意,Windows不是实时操作系统,因此无论您选择什么机制,时间都会有一定的差异。
您没有说明此函数是否执行任何类型的UI更新,但以防万一,您还应该知道回调函数将在不同的线程上执行,因此在某些情况下(如执行UI更新),您需要采取适当的操作将请求返回到UI线程。
要将请求返回到UI线程,您可以执行以下操作
对于WinForms,您可以使用Control.Invoke 对于WPF,您可以使用Dispatcher.Invoke 或者Async变体BeginInvoke

0

你可以使用这个,只要确保你所做的任何操作都是线程安全的。


using System.Threading;

public void DoStuff(IPerson person)
{
    new Timer(ProcessPerson, person, 0, 20000);
}

public void ProcessPerson(object threadState)
{
   IPerson person = threadState as IPerson;
   // do your stuff
}

.NET框架中至少有3个名为“Timer”的类(http://msdn.microsoft.com/en-us/magazine/cc164015.aspx)。您应该澄清您正在谈论哪一个。 (我假设从构造函数中,您指的是[System.Threading.Timer](http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx)) - Simon P Stevens
是的,我应该更清楚一些。编辑以包括System.Threading命名空间。另外,需要注意的是,我的解决方案并不能保证ProcessPerson仅在20秒后被调用,它会每20秒调用一次ProcessPerson,无论上一个ProcessPerson是否完成。 - Adam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接