刚才有一些关于计时器和线程的混淆,见下面的例子,两个代码都提供相同的结果(每隔60秒做一些检查),所以什么时候应该使用计时器什么时候我应该使用线程来处理作业他们提供的结果相同吗?
使用线程:
Thread checkJob = new Thread(checkStatus);
checkJob.Start();
protected void checkStatus()
{
//Do Checking here
Thread.Sleep(60000);
}
使用计时器:
public Form1()
{
InitializeComponent();
Timer time = new Timer();
time.Interval = 60000;
time.Tick += time_Tick;
time.Enabled = true;
}
void time_Tick(object sender, EventArgs e)
{
//Do Checking here
}
答案 0 :(得分:5)
如果定期执行的任务非常短,并且不会妨碍计时器运行的线程的处理,那么计时器是一个合理的选择。
另一方面,如果周期性任务需要花费大量时间,并且你不能让主线程中断执行它,那么单独的专用线程是一个不错的选择。
答案 1 :(得分:4)
这取决于您使用的计时器。如果您使用的是WinForms计时器,那么您的回调将在gui线程上触发。如果你有很多工作要做,那么这将导致你的应用程序阻塞,直到你完成,这将导致糟糕的用户体验。
如果你正在使用其中一个计时器,那么它们将触发线程池中的一个线程。即使在这里你也要避免做任何事情,但它不会阻止你的gui线程。但是,您需要确保使用BeginInvoke
方法封送任何对gui的调用。
如果你在每次计时器触发时都有长时间运行的任务,那么启动自己的线程是很好的,但是你需要再次将调用封回到gui线程。而不是使用Thread.Sleep
,最好使用Event
,以便您可以检测系统的其余部分何时关闭:
ManualResetEvent stopEvent = new ManualResetEvent(false);
Thread checkJob = new Thread(checkStatus);
checkJob.Start();
protected void checkStatus()
{
//Do Checking here
while(stopEvent.Wait(60000) == false)
{
// Do processing
}
}
现在您可以通过调用stopEvent.Set()
答案 2 :(得分:2)
您可以将线程视为“子流程”;一个进程可以有多个线程,允许它并行执行多个操作。线程是一种昂贵的系统资源;它在活动时使用CPU,并分配自己的调用堆栈(默认为1MB)。使用线程执行定期操作是浪费宝贵的资源,并且不能很好地扩展。
另一方面,计时器要便宜得多。它只是一个时间控制的触发器,大部分时间都不执行任何操作,除非是时候执行代码。在您的情况下,这是正确的选择。
答案 3 :(得分:1)
我建议使用Timer - 它更适合资源消耗。 设置新线程非常广泛。 顺便说一下,如果你想使用Thread,你应该将它设置为IsBackground = true,这样它就可以在应用程序关闭时完成它的执行。