使用while(true)循环创建线程是否比在C#中使用计时器更好?
我知道c#允许使用以下计时器:使用while(true)循环创建线程是否比在C#中使用计时器更好?,c#,C#,我知道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 my
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
}
但是,我看到他们没有使用Timer
,而是创建了一个线程来实现自己的计时器:
var task = new Task(Run());
task.start();
protected void run ()
{
while (true)
{
Thread.sleep(1000/60);
//Do something
}
}
与更简单的
计时器相比,使用第二种方法有什么好处吗?没有。绝对没有理由使用第二种方法。尽管两种方法都不精确,第一种方法更精确:考虑一种情况,您标记的代码<代码> //做某事< /C> > 100毫秒,然后调用<代码> //做某事将是<代码> 1000/60 + 100 < /代码>,而不是<代码> 1000/60 > /代码>在您提供的定时器上, < P>在提供定时器的平台上,我总是建议您使用计时器,因为它们的实现可能比使用Thread.sleep
更有效。问题是sleep
会完全阻塞线程,浪费整个线程只是为了通知另一个线程
另一方面,计时器可以管理多个时间,并且只使用一个线程。它甚至可以使用操作系统提供的一些extas。但不仅如此,它甚至可能会考虑一些调度成本,以便更精确(至少理论上是这样)。唯一可能的好处可能是卸载到后台线程。在您的示例中,计时器的事件处理程序将在UI线程上运行,而后者将在后台线程上运行
我会使用async/wait
或ContinueWith
方法,而不是Thread.Sleep
。由于各种原因,有一些计时方法优于System.Windows.Forms.Timer
,但没有一种方法包括您自己的线程管理(这是一种资源浪费,因为每个线程都有大量的内存开销)
以下是文章底部的表格:
+---------------------------------------+----------------------+---------------------+------------------+
| | 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)
但是,需要注意的是,无论是计时器事件还是Thread.Sleep
首先都不能保证或期望精确。虽然100ms的差异很少见,Thread.Sleep
通常可以变化10-20ms@JasonWatkins你是对的,值得一提的是,这两种方法都不是特别精确的。谢谢!虽然在技术上是正确的,但应该注意的是,我的任务管理器目前显示了1265个打开的线程。再显示一个线程不会有任何实际的区别。仅仅因为你可以马虎,并不一定意味着你应该:)在UI线程上运行的窗体计时器是一个功能。异步计时的更好解决方案是使用System.Timers.Timer
或System.Threading.Timer
。是。同意。我想他是在问使用任务超时(表单)有什么好处。我想我提到了计时器的事件处理程序将在UI线程上运行由于Thread.Sleep会阻塞线程,他可以使用Task.Delay作为非阻塞延迟。当然,如果我可以选择的话,我只会使用System.Threading.Timer
。这样想。假设你想在看电视《谁是医生》的时候提醒一下。你会雇佣一个工作就是每天睡23小时59分钟,然后每天睡一分钟的人来提醒你是时候给谁当医生了吗?给他全天24小时的工作报酬?因为这就是你在后一种技术中所做的。线很贵。除非你有很多工作要做,否则不要雇佣线程