2009-07-24 77 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