2009-07-24 10 views
1

私はこれを理解しようとしている私の脳をつかまえています。ここにシナリオがあります。私は本質的にイベントが発生するはずの様々な時間を含むソートされた静的リストを持っています。可視化のために:だからプリエンプティブ待ち行列を実装する最も効率的な方法は?

+-----------------------+ 
| Time | LastUpdate | 
|-----------------------| 
| 1 | 03:10:00 | 0 
| 2 | 03:10:00 | 1 
| 2 | 03:10:00 | 2 
| 3 | 03:10:00 | 3 
| 3 | 03:10:00 | 4 
| 4 | 03:10:00 | 5 
+-----------------------+ 

、メソッドを介して初めて、lastTimeプロパティはnullになるだろう、それは「いくつかの作業を行う」と現在の時刻にlastTimeプロパティを設定します。 timeプロパティは、アイテムをいつ再実行する必要があるかを示します。例えば、要素0はlastTime03:10:00であり、時間が1であるので、03:11:00で実行する必要があり、要素1と要素2の両方ともlastTime03:10:00であり、両方とも03:12:00で実行する必要があります。 。ここで

は、私が行くているもののラフな実装です:

public static IList<Item> _list; 

public void DoSomething() 
{ 
    while (true) 
    { 
     for (int i = 0; i < _list.Count; i++) 
     { 
      var item = new Item(); 

      if (DateTime.MinValue.Equals(_list[i].LastUpdate)) 
      { 
       item = DoWork(_list[i].Url); 
       _list[i].LastUpdate = item.LastUpdate; 
       Console.WriteLine(item.Title + " @ " + item.LastUpdate + "; i = " + i); 
      } 
      else 
      { 
       var timeToSleep = ((_list[i].LastUpdate.AddMinutes(_list[i].Time)).Subtract(DateTime.Now)); 

       if (timeToSleep.TotalMilliseconds > 0) 
       { 
        for (int j = 0; j < i; j++) 
        { 
         var lastRet = _list[j].LastUpdate.AddMinutes(_list[j].Time); 
         var nextFetch = DateTime.Now.Add(timeToSleep); 

         if (lastRet < nextFetch) 
         { 
          item = DoWork(_list[i].Url); 
          _list[i].LastUpdate = item.LastUpdate; 
          Console.WriteLine(item.Title + " @ " + item.LastUpdate + "; i = " + i); 
         } 
        } 
       } 

       if (timeToSleep.TotalMilliseconds > 0) 
       { 
        Console.WriteLine("Sleeping until: " + DateTime.Now.Add(timeToSleep)); 
        System.Threading.Thread.Sleep(timeToSleep); 
       } 

       item = DoWork(_list[i].Url); 
       _list[i].LastUpdate = item.LastUpdate; 
       Console.WriteLine(item.Title + " @ " + item.LastUpdate + "; i = " + i); 
      } 
     } 

     Console.WriteLine("--------------------------"); 
    } 
} 

行われる必要があるものがない場合は、リストの次の項目を更新する準備が整うまで、それはスリープします。より頻繁に更新されるアイテムが、更新頻度の低いアイテムが再び更新されるまで待つ必要がないように、内部forループが配置されます。理想的なシナリオでは、スリープを呼び出す前に更新が必要な項目があるかどうかを確認します。現在のアイテムの上にあるアイテムが更新される前に更新が必要な場合は、そのアイテムを更新してください。そうでない場合は、現在のアイテムはスリープ状態になり、更新準備が整うまで待機します。私はこれが理にかなってほしい。

私はこれについて完全に間違っていますか?これには簡単な解決策がありますか?私はすべての提案に開放されています。また、このリストは何千ものアイテムに成長する可能性があることに注意してください。前もって感謝します。

答えて

1

私はあなたの問題の説明を完全に理解していませんが、これは不必要に複雑です。どのように:タスクの数が大きくなると

public static IList<Item> _list; 

public void DoSomething() 
{ 
    while (true) 
    { 
     DateTime minDate = DateTime.MaxValue; 

     for (int i = 0; i < _list.Count; i++) 
     { 
      DateTime nextExecution = _list[i].LastUpdate.AddMinutes(_list[i].Time); 

      if (nextExecution <= DateTime.Now) 
      { 
       var item = DoWork(_list[i].Url); 
       _list[i].LastUpdate = item.LastUpdate; 
       nextExecution = _list[i].LastUpdate.AddMinutes(_list[i].Time); 
       Console.WriteLine(item.Title + " @ " + item.LastUpdate + "; i = " + i); 
      } 

      if (nextExecution < minDate) 
       minDate = nextExecution; 
     } 

     TimeSpan timeToSleep = minDate.Subtract(DateTime.Now)); 

     if (timeToSleep.TotalMilliseconds > 0) 
     { 
      Console.WriteLine("Sleeping until: " + minDate); 
      System.Threading.Thread.Sleep(timeToSleep); 
     } 
    } 
} 

、あなたは次の計算された実行時間によって注文されたリンクリストを維持することができます。そうすれば、反復ごとにリスト全体をループする必要はありません。

+0

ええ、私は不必要に複雑すぎるようでした。あなたのソリューションは正常に動作するようです。助けてくれてありがとう。 – user135383

関連する問題