【问题标题】:What are the differences between System.Threading.Timer and creating your own background tick thread in C#System.Threading.Timer 和在 C# 中创建自己的后台滴答线程有什么区别
【发布时间】:2012-01-19 15:38:58
【问题描述】:

我有一个结构如下的背景刻度函数:

    System.Threading.Thread myTimerThread = new Thread(this.Tick);

    private void Tick(){
       do{
          //do stuff
          System.Threading.Sleep(1000L);
       }while(true)    
    }

但是,还有一个 System.Threading.Timer 类可以为我执行此操作。使用 System.Threading 中的内置 Timer 类与使用 Tick 函数创建自己的后台线程有什么区别?

【问题讨论】:

    标签: c# .net multithreading timer


    【解决方案1】:

    与您自己的专用线程相比,Timer 类的重量非常轻,效率更高,后者在无限循环中休眠指定时间。

    请阅读Thread.Sleep is a sign of a poorly designed program,了解 Thread.Sleep 的实际工作原理以及它如何浪费完整的线程和资源

    另一方面,System.Threading.Timer 将使用 ThreadPool 线程来执行计时器。如我的 MSDN 所述,使用 Timer 类的其他好处

    创建计时器时,您可以指定在 方法的第一次执行(到期时间),以及之间的等待时间 随后的处决(期间)。您可以使用 Change 方法更改这些值,或禁用计时器。

    在基于线程的方法中您不会获得这些好处

    【讨论】:

    • 冒昧地将引用的文本从代码块更改为引用。
    • 我阅读了您在 Thread.Sleep 上发布的文章,我完全明白为什么创建任意滴答线程并使用循环和睡眠是非常昂贵且不可取的。
    【解决方案2】:

    首先,除非您正在执行长时间运行的操作,否则请使用线程池。您自己的计时器与 System.Threading.Timer 之间的区别在于 System.Threading.Timer 使用硬件中断来了解何时适合执行滴答。它会比仅仅休眠 x 毫秒更准确(尽管多媒体计时器会更准确),后者必须等到线程调度程序获得控制权,然后您的线程才能获得控制权。

    您还应该知道,如果您正在做任何会影响线程上的 Gui 的事情,您应该使用适当的 Gui 版本的计时器,否则您的滴答声将不会出现在您必须访问 Gui 控件的线程上,您将必须调用才能进入正确的线程。对于 Windows 窗体,它是 System.Windows.Forms.Timers,对于 WPF 和 Silverlight,它是 System.Windows.Threading.DispatcherTimer。有关线程和计时器的更多信息,我强烈推荐 Joseph Albahari 的免费电子书Threading in C#

    【讨论】:

    • 我知道 System.Windows.Forms.Timer,但是,当 Application.DoEvents() 被调用时,滴答声将再次排队,因此在我的场景中这对于可靠的滴答声函数是不可取的.
    • 你永远不必调用 Application.DoEvents(),如果你“做错了”,应该考虑重新设计你正在做的事情。 DoEvents 仅存在于 VB6 中,因为您没有能力执行多线程,而且有些事情需要很长时间。它总是会导致问题和难以调试竞争条件,如果可能的话,尽量避免它。听杰夫:codinghorror.com/blog/2004/12/is-doevents-evil.html
    【解决方案3】:

    您可以使用 System.Threading.Timer 进行更多控制。您可以对计时器进行编程,使其每隔 1/4 秒检查某个线程或事件,直到它运行,然后您可以使用 dispose 方法处置计时器。它更加灵活,因为您可以对其进行编程以做任何您想做的事情,并且更加准确。

    当您使用 Thread.Sleep 时,您实际上只有一个选择,那就是强制程序“休眠” x 秒。据我所知,您无法处理它,对其进行计时,对其进行协调以使其尽早停止。等等。底线是,即使您的程序运行完毕,Thread.Sleep 也会继续强制程序进入睡眠状态。可以对 Threading.Timer 进行编程,使其在程序完成运行时停止。

    【讨论】:

      猜你喜欢
      • 2010-11-22
      • 1970-01-01
      • 2017-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-05
      • 1970-01-01
      相关资源
      最近更新 更多