3

私は仕事のリストを持っています。各ジョブには独自の実行時間があります。彼らは時が来たら走る必要があります。私は2つの異なる方法を考えています。

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
}

2番目の方法:

アプリケーションが起動したら、ジョブリスト内のジョブごとに新しいスレッドを作成します。これらの作成されたスレッドはすべて開始されます。ジョブのスレッドが開始されると、ジョブのスレッドはジョブの実行時間をチェックします。

例えば ​​:

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個になります。そして、これらの10個のスレッドは決して終了しません。眠る、続く、眠る、続く...

スレッドがこれほど長い時間スリープするのは正常ですか?どちらの方法を使用すればよいですか?またはそのようなことをする別の方法はありますか?

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 に答える