3

我有一份工作清单。每个作业都有自己的运行时间。他们需要在时机成熟时奔跑。我认为两种不同的方式。

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 的线程启动时,Job 的线程会检查 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);
       }
    }
}

如果有十个作业,就会有十个线程。而这十根线永远不会结束。会睡觉,会继续,会睡觉,会继续……

线程休眠这么长时间正常吗?我应该使用哪种方式?还是有另一种方法来做这样的事情?

4

1 回答 1

7

在大多数情况下,这两种方法都是不正确的。此类问题的通常解决方案是使用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(),您的应用程序将变得非常无响应。

于 2012-06-19T10:38:27.760 回答