Я ломал голову, пытаясь понять это. Вот сценарий. По сути, у меня есть отсортированный статический список, который содержит разное время, когда должно произойти событие. Для визуализации:
+-----------------------+
| 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 имеет lastTime
из 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 он проверит, не нужно ли обновлять какие-либо элементы над ним. Если какие-либо элементы над текущим элементом потребуют обновления до того, как текущий элемент перейдет в спящий режим, обновите их. Если нет, то текущий элемент вызовет Sleep, чтобы дождаться, когда он будет готов к обновлению. Я надеюсь в этом есть смысл.
Я делаю это совершенно неправильно? Есть ли более простое решение для этого? Я открыт для любых предложений. Кроме того, имейте в виду, что этот список потенциально может вырасти до тысяч элементов. Заранее спасибо.