我一直在试图弄清楚这件事。这是场景。我基本上有一个排序的静态列表,其中包含一个事件应该发生的不同时间。对于可视化:最有效的方式来实施抢先等候队列?
+-----------------------+
| 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都具有lastTime
的03: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之前检查它上面的任何项是否需要更新。如果当前项目上方的任何项目在当前项目休眠之前需要更新,请继续并更新它们。如果不是,则当前项目将调用睡眠等待,直到它准备好被更新。我希望这是有道理的。
我对这完全错了吗?有更简单的解决方案吗?我愿意接受任何和所有建议。另外,请记住,此列表可能会增长到数千个项目。提前致谢。
是的,它似乎是我不必要地过度复杂的事情。您的解决方案似乎工作正常。谢谢您的帮助。 – user135383 2009-07-27 14:04:25