我有一份工作清单。每个工作都有自己的运行时间。它们需要在时间到来时运行。我认为有两种不同的方式。
public class Job
{
public int JobPeriod {get;set;} // for example as hour: daily = 24, weekly = 7 * 24, monthly = 30 * 24
public DateTime RunTime {get;set}
}
第一种方式:
我开始一个新的主线程。该线程以特定时间间隔(5秒,10秒等)检查作业。当作业的运行时间到来时,主线程将开始并完成作业。以这种方式不断运行的主线程。
while (true)
{
lock (Locker)
{
// checks job list.
var jobs = foo.GetIncomingTimeJobs();
foreach (var job in jobs)
{
ParameterizedThreadStart ts = RunJob;
var th = new Thread(ts);
th.Start(job);
}
Thread.Sleep(10000);
}
}
public void RunJob(Job job)
{
// do somethings
}
第二种方式:
当应用程序启动时,我为作业列表中的每个作业创建一个新线程。所有这些创建的线程都将启动。当Job的线程启动时,作业的线程会检查作业的运行时间。
例如:
var jobs = foo.GetAllJobs();
foreach (var job in jobs)
{
ParameterizedThreadStart ts = RunJob;
var th = new Thread(ts);
th.Start(job);
}
public void RunJob(Job job)
{
while (true)
{
lock (Locker)
{
// do somethings
var period = job.JobPeriod * 60 * 1000;
Thread.Sleep(period);
}
}
}
如果有10个工作,则会有10个线程。而这十个线程永远不会结束。会睡觉,会继续,会睡觉,会继续......
线程长时间睡眠是否正常?我应该使用哪种方式?或者还有另一种方法可以做这样的事情吗?
答案 0 :(得分:5)
这两种方法在大多数情况下都是不正确的。针对此类问题的常用解决方案是使用System.Threading.Timer。您的案例的示例代码可能如下所示:
private void CheckJobs(object state)
{
lock (Locker)
{
// checks job list.
var jobs = foo.GetIncomingTimeJobs();
foreach (var job in jobs)
{
var thread = new Thread(foo);
thread.Start();
}
}
}
private void StartProcessing()
{
var timer = new System.Threading.Timer(CheckJobs, null, 0, 10000);
}
当您调用StartProcessing()函数时,将初始化计时器,并且每10秒检查一次作业列表。
如果您使用Thread.Sleep(),您的应用程序将变得非常反应迟钝。