C#中的线程与计时器

时间:2011-06-07 13:18:26

标签: c# timer

我有两种检查数据的实现:

使用System.Timers.Timer

public void startTimer()
{
    try
    {
         System.Timers.Timer timer = new System.Timers.Timer(1);
         timer.AutoReset = true;
         timer.Elapsed += new ElapsedEventHandler(commStart);
         timer.Enabled = true;
         timer.Start();
    }
    catch(Exception ex){}
}

private void commStart(){object sender, EventArgs eArgs}

使用Thread

public void startThread()
{
   Thread threadGeneralComm = new Thread(new ThreadStart(commStart));

   threadGeneralComm.Start()
}

private void commStart()
{
   while(true)
   {
       // checking data
       Thread.Sleep(1);
   }
}

所以你可以看到,两种实现方式都会检查数据并等待1毫秒。人们抱怨我使用Timer比使用Thread更糟糕,使用Thread的速度要快10倍。是这样的吗?

4 个答案:

答案 0 :(得分:12)

两种选择都很差。它们是轮询方法,因此在没有数据时会毫无理由地使用CPU。

如果您不能使用事件驱动方法,那么您应该根据阻塞队列寻找解决方案。

答案 1 :(得分:8)

Windows应用程序基于事件驱动架构。鼠标移动,按键,显示UI,移动窗口,调整大小等所有这些都是事件。当应用程序发生事件时,Windows会将该事件分配给名为Application Queue的事件,窗口应用程序应具有从应用程序队列中获取事件的连续循环,并使用Dispatcher处理事件。

通过这种方式,TIMER是一个事件,当注册时,操作系统会将定时器消息放在应用程序队列中,以便应用程序可以处理定时器。 TIMER始终适用于UI线程。因此,是否将TIMER事件放在应用程序队列上取决于操作系统。当操作系统太忙时,您可能会错过计时器事件。

线程具有独立的执行上下文,保证执行。

答案 2 :(得分:7)

解决方案之间的差异
解决方案之间的主要区别在于,计时器一个将每毫秒调用一次,而单个线程解决方案将在每次数据检查之间等待一毫秒。

在计时器解决方案中,数据检查将并行发生 - 每个回调都在线程池上的不同线程上完成。

例如,当每个间隔10ms使用一个定时器并且回调方法需要20ms来处理时,线程池中的多个线程上会有几个活动的回调。

单线程更好(在这种情况下)
假设在您的示例中处理时间超过1毫秒,它解释了为什么它比单个线程慢得多。

我认为可能有一个比这更好的解决方案 - 使用数据库触发器,某些事件或回调......但如果获取信息的唯一方法是主动检查数据,那么使用单线程解决方案更好

答案 3 :(得分:4)

如果您要等待数据作为文件出现,您可以使用FileSystemWatcher

轮询总是资源紧张,最好使用Hollywood Principle Design Pattern