繁体   English   中英

C# 中的线程与计时器

[英]Thread vs Timer in C#

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

使用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 倍。 是这样吗?

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

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

Windows 应用程序基于事件驱动架构。 鼠标移动、按键、显示 UI、移动 window、调整大小等都是事件。 当您的应用程序发生事件时,windows 将该事件分配给称为应用程序队列的东西,并且 window 应用程序应具有从应用程序队列获取事件的连续循环,并使用调度程序处理事件。

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

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

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

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

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

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

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

如果您正在等待数据以文件的形式出现,您可以使用FileSystemWatcher

轮询总是资源密集型的,最好使用好莱坞原则设计模式

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM