4

我知道 C# 允许使用计时器:

System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
timer.Interval = 1000/60;
timer.Tick += new EventHandler(TimerEventProcessor);
timer.Start();


private static void TimerEventProcessor(Object myObject, EventArgs myEventArgs)
{
    //Do something
}

但是,我在这个 YouTube 教程中看到,他们没有使用Timer他们创建了一个实现自己的计时器的线程:

var task = new Task(Run());
task.start();

protected void run ()
{
    while (true)
    {
        Thread.sleep(1000/60);
        //Do something
    }
}

使用第二种方法比使用更简单的方法有什么好处Timer吗?

4

5 回答 5

4

System.Windows.Forms.Timer由于各种原因,有一些计时方法比它更好,但没有一个包括您自己的线程管理(这是一种资源浪费,因为每个线程都有大量的内存开销)。

比较 .NET Framework 类库中的计时器类

这是文章底部的表格:

+---------------------------------------+----------------------+---------------------+------------------+
|                                       | System.Windows.Forms |    System.Timers    | System.Threading |
+---------------------------------------+----------------------+---------------------+------------------+
| Timer event runs on what thread?      | UI thread            | UI or worker thread | Worker thread    |
| Instances are thread safe?            | No                   | Yes                 | No               |
| Familiar/intuitive object model?      | Yes                  | Yes                 | No               |
| Requires Windows Forms?               | Yes                  | No                  | No               |
| Metronome-quality beat?               | No                   | Yes*                | Yes*             |
| Timer event supports state object?    | No                   | No                  | Yes              |
| Initial timer event can be scheduled? | No                   | No                  | Yes              |
| Class supports inheritance?           | Yes                  | Yes                 | No               |
+---------------------------------------+----------------------+---------------------+------------------+

* Depending on the availability of system resources (for example, worker threads)
于 2013-03-22T02:08:22.957 回答
3

虽然这两种方法都不准确,但第一种方法更精确一些:考虑一种情况,您标记的代码//Do something需要 100 毫秒。那么调用之间的间隔//Do something将是1000/60+100,而不是1000/60您预期的那样。

于 2013-03-22T01:57:32.257 回答
2

在为您提供计时器的平台上,我始终建议您使用计时器,因为它们的实现可能比 with 更有效Thread.sleep。问题是完全sleep阻塞了线程,只是为了通知另一个线程而浪费了整个线程。

另一方面,计时器可以管理多个时间并且只使用一个线程。它甚至可能使用操作系统提供的一些附加功能。但不仅如此,它甚至可能会考虑一些调度成本以更精确(至少在理论上)。

于 2013-03-22T01:57:48.507 回答
2

唯一可能的好处可能是卸载到后台线程。在您的示例中,计时器的事件处理程序将在 UI 线程上运行,而后者将在后台线程上运行。

我会使用带有or方法的Task.Delay来代替。async/awaitContinueWithThread.Sleep

于 2013-03-22T02:00:15.257 回答
1

不,绝对没有理由使用第二种方法。

于 2013-03-22T01:56:25.763 回答