简体   繁体   English

C# 中的线程与计时器

[英]Thread vs Timer in C#

I have two implementations of checking for data coming:我有两种检查数据的实现:

Using System.Timers.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}

Using Thread :使用Thread

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

   threadGeneralComm.Start()
}

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

So you can see, both of the implementation ways, it will check for data and wait for 1 millisecond.所以你可以看到,两种实现方式,它都会检查数据并等待1毫秒。 People are complaining to me that using Timer is worse than using Thread, and using a Thread is 10 times faster.人们向我抱怨说使用 Timer 比使用 Thread 更糟糕,而使用 Thread 的速度要快 10 倍。 Is that the case?是这样吗?

Both options are poor.两种选择都很差。 They are polling methods and so will use CPU for no reason when there is no data.它们是轮询方法,因此在没有数据时会无缘无故地使用 CPU。

If you can't use an event driven approach then you should look for a solution based on a blocking queue.如果您不能使用事件驱动的方法,那么您应该寻找基于阻塞队列的解决方案。

Windows applications are based on event driven architecture. Windows 应用程序基于事件驱动架构。 Mouse move, key press, showing UI, moving window, resizing etc all of them are events.鼠标移动、按键、显示 UI、移动 window、调整大小等都是事件。 When there is an event to your application, windows assign that event to something called Application Queue and the window application shall have continous loops for getting the event from application queue, and process the event using the Dispatcher.当您的应用程序发生事件时,windows 将该事件分配给称为应用程序队列的东西,并且 window 应用程序应具有从应用程序队列获取事件的连续循环,并使用调度程序处理事件。

In this way, a TIMER is an event, when registered, the OS will put the timer message on the application queue so that the application can process the timer.这样,一个TIMER就是一个事件,注册后,操作系统会将定时器消息放到应用队列中,以便应用程序处理这个定时器。 The TIMER always works on the UI thread. TIMER 始终在 UI 线程上工作。 So it is up to the operating system whether to put the TIMER event on the app queue or not.因此,是否将 TIMER 事件放入应用队列取决于操作系统。 When the OS is too busy, you may miss your timer events.当操作系统太忙时,您可能会错过计时器事件。

A thread has an independent execution context, which is guaranteed to be executed.线程具有独立的执行上下文,保证执行。

The difference between the solutions解决方案的区别
The main difference between the solutions is that the timer one will be called every millisecond, while the single thread solution will wait one millisecond between every data check.解决方案之间的主要区别在于,计时器将每毫秒调用一次,而单线程解决方案将在每次数据检查之间等待一毫秒。

In the timer solution, the data checking will happen in parallel - every callback is done on a different thread on the thread pool.在计时器解决方案中,数据检查将并行发生 - 每个回调都在线程池中的不同线程上完成。

For example, when using a timer every with 10ms interval and the callback method takes 20ms to process, there'll be several active callbacks on multiple threads from the threads pool.例如,当使用间隔为 10 毫秒的计时器并且回调方法需要 20 毫秒来处理时,线程池中的多个线程上会有多个活动的回调。

Single thread is better (in this case)单线程更好(在这种情况下)
Assuming that in your example the processing takes more than 1ms, it explains why it is much slower than having a single thread.假设在您的示例中处理时间超过 1 毫秒,它解释了为什么它比单线程慢得多。

I assume that there might be a better solution than this - using a DB trigger, some event or callback... But if the only way to get the information is by actively checking the data then using the single thread solution is better.我认为可能有比这更好的解决方案 - 使用数据库触发器、一些事件或回调......但如果获取信息的唯一方法是主动检查数据,那么使用单线程解决方案会更好。

If you are waiting for Data to come to comes as a file, you can use FileSystemWatcher如果您正在等待数据以文件的形式出现,您可以使用FileSystemWatcher

Polling is always resource intenstive, better to use Hollywood Principle Design Pattern轮询总是资源密集型的,最好使用好莱坞原则设计模式

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

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