Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用while(true)循环创建线程是否比在C#中使用计时器更好?_C# - Fatal编程技术网

使用while(true)循环创建线程是否比在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

我知道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
}
但是,我看到他们没有使用
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小时的工作报酬?因为这就是你在后一种技术中所做的。线很贵。除非你有很多工作要做,否则不要雇佣线程