2009-07-24 78 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屬性將是零,所以它會「做一些工作」,並設置lastTime屬性設置爲當前時間。 time屬性表示該項目何時需要再次執行。例如,因爲元素0具有的03: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循環放置到位以防止更頻繁更新的項目必須等待,直到不再頻繁的項目被更新,然後才能夠再次自我更新。在理想的情況下,它會在調用Sleep之前檢查它上面的任何項是否需要更新。如果當前項目上方的任何項目在當前項目休眠之前需要更新,請繼續並更新它們。如果不是,則當前項目將調用睡眠等待,直到它準備好被更新。我希望這是有道理的。

我對這完全錯了嗎?有更簡單的解決方案嗎?我願意接受任何和所有建議。另外,請記住,此列表可能會增長到數千個項目。提前致謝。

回答

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 2009-07-27 14:04:25