C#中的线程与计时器

oli*_*dev 3 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}
Run Code Online (Sandbox Code Playgroud)

使用Thread:

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

   threadGeneralComm.Start()
}

private void commStart()
{
   while(true)
   {
       // checking data
       Thread.Sleep(1);
   }
}
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*nan 12

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

如果您不能使用事件驱动方法,那么您应该寻找基于阻塞队列的解决方案.


小智 9

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

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

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

  • 计时器不仅限于UI线程.不保证执行线程. (5认同)

Eli*_*sha 7

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

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

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

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

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