我有两种检查数据的实现:
使用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倍。是这样的吗?
答案 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