/// <summary> /// init the active items and free positions. /// </summary> private void Init() { long current = 10; long length = this.RecordStream.Length; while (length >= current + this.recordlen) { RepeatItem <TValue> item = GetRecord(current); if (item == null) { this.FreePositions.Add(current); } else { item.Item = GetTask(item.BlockPosition); this.RepeatTaskList.Add(item); } current = current + this.recordlen; } if (current != length) { // if the current is the not the end, there must be some bytes missing. this.RecordStream.SetLength(current + this.recordlen); } }
/// <summary> /// This item just get executed, and should be updated now. /// </summary> /// <param name="item"></param> private void UpdateExecuteTime(RepeatItem <TValue> item) { DateTime executetime = DateTime.Now; lock (_object) { RepeatItem <TValue> currentitem = this.RepeatTaskList.Find(o => o.id == item.id); if (currentitem != null) { currentitem.LastExecute = executetime; currentitem.NextExecute = CalculateNextExecuteTime(currentitem); long executetimeposition = item.id + 16; long tickexecutetime = executetime.Ticks; long NextExecutionPosition = item.id + 24; long tickNextExecution = currentitem.NextExecute.Ticks; this.RecordStream.Position = executetimeposition; this.RecordStream.Write(BitConverter.GetBytes(tickexecutetime), 0, 8); this.RecordStream.Position = NextExecutionPosition; this.RecordStream.Write(BitConverter.GetBytes(tickNextExecution), 0, 8); } } }
/// <summary> /// Update this task content of this record. /// </summary> /// <param name="item"></param> public void UpdateTask(RepeatItem <TValue> item) { long blockposition = AddTask(item.Item); item.BlockPosition = blockposition; UpdateSchedule(item); }
/// <summary> /// Dequeue one item from the list the due tasks, and update its last execute time. /// </summary> /// <returns></returns> public RepeatItem <TValue> DequeueItem() { foreach (var item in this.RepeatTaskList) { if (item.NextExecute <= DateTime.Now) { RepeatItem <TValue> one = Helper.TypeHelper.DeepCopy <RepeatItem <TValue> >(item); UpdateExecuteTime(one); return(one); } } return(null); }
/// <summary> /// Add a new item to the repeating task list. /// </summary> /// <param name="Item"></param> public void Add(RepeatItem<TValue> Item) { long blockposition = AddTask(Item.Item); Item.BlockPosition = blockposition; if (Item.NextExecute == default(DateTime)) { Item.NextExecute = CalculateNextExecuteTime(Item); } AddRecord(Item); // also need to add to current list. this.RepeatTaskList.Add(Item); }
/// <summary> /// Add the record item to the record table. /// </summary> /// <param name="item"></param> /// <returns></returns> private long AddRecord(RepeatItem <TValue> item) { byte[] bytes = this.ToRecordBytes(item); int bytelen = bytes.Length; lock (_object) { Int64 insertposition = GetRecordInsertPosition(); RecordStream.Position = insertposition; RecordStream.Write(bytes, 0, bytelen); item.id = insertposition; return(insertposition); } }
public RepeatItem <TValue> ParseRecordBytes(byte[] bytes) { if (bytes[0] != startbyteone && bytes[1] != startbytetwo) { return(null); } if (bytes[2] == this.recordDeletedByteValue) { return(null); } RepeatItem <TValue> item = new RepeatItem <TValue>(); if (bytes[2] == 1) { item.IsActive = true; } else if (bytes[2] == 0) { item.IsActive = false; } else { /// potential errror. return(null); } item.Frequence = (RepeatFrequence)bytes[3]; item.FrequenceUnit = BitConverter.ToInt32(bytes, 4); long tickStartTime = BitConverter.ToInt64(bytes, 8); long tickLastExecute = BitConverter.ToInt64(bytes, 16); long tickNextExecute = BitConverter.ToInt64(bytes, 24); item.StartTime = new DateTime(tickStartTime); item.LastExecute = new DateTime(tickLastExecute); item.NextExecute = new DateTime(tickNextExecute); item.BlockPosition = BitConverter.ToInt64(bytes, 32); return(item); }
/// <summary> /// convert the meta info of a repeating task into bytes. /// </summary> /// <param name="item"></param> /// <returns></returns> private byte[] ToRecordBytes(RepeatItem <TValue> item) { byte[] bytearray = new byte[this.recordlen]; bytearray[0] = startbyteone; bytearray[1] = startbytetwo; bytearray[this.recordlen - 2] = startbyteone; bytearray[this.recordlen - 1] = startbytetwo; if (item.IsActive) { bytearray[2] = 1; } else { bytearray[2] = 0; } bytearray[3] = (byte)item.Frequence; //frequence unit. System.Buffer.BlockCopy(BitConverter.GetBytes(item.FrequenceUnit), 0, bytearray, 4, 4); long tickStartTime = item.StartTime.Ticks; long tickLastExecute = item.LastExecute.Ticks; long tickNextExecute = item.NextExecute.Ticks; //starttime System.Buffer.BlockCopy(BitConverter.GetBytes(tickStartTime), 0, bytearray, 8, 8); //last execute System.Buffer.BlockCopy(BitConverter.GetBytes(tickLastExecute), 0, bytearray, 16, 8); //next execute System.Buffer.BlockCopy(BitConverter.GetBytes(tickLastExecute), 0, bytearray, 24, 8); // block position. System.Buffer.BlockCopy(BitConverter.GetBytes(item.BlockPosition), 0, bytearray, 32, 8); return(bytearray); }
public RepeatItem <TValue> Get(Int64 id) { foreach (var item in RepeatTaskList) { if (item.id == id) { return(Helper.TypeHelper.DeepCopy <RepeatItem <TValue> >(item)); } } RepeatItem <TValue> record = GetRecord(id); if (record != null) { this.RepeatTaskList.Add(record); return(Helper.TypeHelper.DeepCopy <RepeatItem <TValue> >(record)); } return(null); }
/// <summary> /// Get the list of all repeating task items that are due to be executed. and update their last execute time accordingly. /// </summary> /// <returns></returns> public List<RepeatItem<TValue>> DequeueItems() { List<RepeatItem<TValue>> items = new List<RepeatItem<TValue>>(); foreach (var item in this.RepeatTaskList) { if (item.NextExecute <= DateTime.Now) { RepeatItem<TValue> one = DeepCopy<RepeatItem<TValue>>(item); items.Add(one); } } // mark every item as executed. foreach (var item in items) { UpdateExecuteTime(item); } return items; }
/// <summary> /// update the schedule info of this record. /// </summary> /// <param name="item"></param> public void UpdateSchedule(RepeatItem <TValue> item) { byte[] bytes = this.ToRecordBytes(item); int bytelen = bytes.Length; lock (_object) { if (item.id > 0) { ContentStream.Position = item.id; ContentStream.Write(bytes, 0, bytelen); } var currentitem = this.RepeatTaskList.Find(o => o.id == item.id); if (currentitem != null) { currentitem = item; } } }
/// <summary> /// get the record schedule information. /// </summary> /// <param name="recordposition"></param> /// <returns></returns> private RepeatItem <TValue> GetRecord(long recordposition) { byte[] recordbytes = new byte[this.recordlen]; lock (_object) { this.RecordStream.Position = recordposition; this.RecordStream.Read(recordbytes, 0, this.recordlen); } RepeatItem <TValue> record = ParseRecordBytes(recordbytes); if (record == null) { return(null); } else { record.id = recordposition; return(record); } }
/// <summary> /// Delete a item. /// </summary> /// <param name="Item"></param> public void Del(RepeatItem <TValue> Item) { Del(Item.id); }
/// <summary> /// Used when an item is get out for execution, calcuate the next execution time. /// </summary> /// <param name="item"></param> /// <param name="LastExecute"></param> /// <returns></returns> public DateTime CalculateNextExecuteTime(RepeatItem <TValue> item) { return(GetNextTryTime(item.Frequence, item.FrequenceUnit, item.StartTime, item.LastExecute)); }