My application has a thread for handling database inserts and updates. Data is added by other threads to a generic queue in the DB thread. The contents of this queue is retrieved and is sequentially inserted to the database by the thread.
To improve performance, I am planning to bring in a priority mechanism so that messages with higher priority should get inserted in the database before those with lower priority.
I implemented a class with a SortedDictionary
for handling the priority. An enum indicating the priority would be the key and a Queue
containing the messages would be the value part of the dictionary.
Please review the following code and provide suggestions on how to improve it. Also if there are any readily available solutions please provide the details.
public class PriorityQueue
{
private Object lockObj;
private SortedDictionary<PQMsgPriority, Queue<PQMessage>> messageDictionary;
public PriorityQueue()
{
lockObj = new object();
messageDictionary = new SortedDictionary<PQMsgPriority, Queue<PQMessage>>();
}
public void Enqueue(PQMessage item)
{
lock (lockObj)
{
if (item != null)
{
if (messageDictionary.ContainsKey(item.MsgPriority))
{
Queue<PQMessage> dataList = messageDictionary[item.MsgPriority];
dataList.Enqueue(item);
}
else
{
Queue<PQMessage> dataList = new Queue<PQMessage>();
dataList.Enqueue(item);
messageDictionary.Add(item.MsgPriority, dataList);
}
}
}
}
public PQMessage Dequeue()
{
lock (lockObj)
{
PQMessage messageData = null;
PQMsgPriority prioKeyDeleteFlag = PQMsgPriority.None;
//If no data available, throw an exception
if (messageDictionary.Count == 0)
throw new InvalidOperationException();
foreach (KeyValuePair<PQMsgPriority, Queue<PQMessage>> item in messageDictionary)
{
Queue<PQMessage> dataList = item.Value;
if (dataList.Count > 0)
messageData = dataList.Dequeue();
else
{
prioKeyDeleteFlag = item.Key;
continue;
}
break;
}
if (prioKeyDeleteFlag != PQMsgPriority.None)
messageDictionary.Remove(prioKeyDeleteFlag);
return messageData;
}
}
public int Count()
{
lock (lockObj)
{
int totalCount = 0;
foreach (KeyValuePair<PQMsgPriority, Queue<PQMessage>> item in messageDictionary)
{
if (item.Value != null)
{
if (item.Value.Count == 0)
continue;
else
{
totalCount = totalCount + item.Value.Count;
continue;
}
}
break;
}
return totalCount;
}
}
public PQMessage Peek()
{
lock (lockObj)
{
PQMessage messageData = null;
//If no data available, throw an exception
if (messageDictionary.Count == 0)
throw new InvalidOperationException();
foreach (KeyValuePair<PQMsgPriority, Queue<PQMessage>> item in messageDictionary)
{
Queue<PQMessage> dataList = item.Value;
if (dataList.Count > 0)
messageData = dataList.Peek();
break;
}
return messageData;
}
}
}
The priority enum is defined as follows:
public enum PQMsgPriority
{
High = 0,
Medium = 1,
Low = 2,
None = 3
}
The priority message is defined as follows:
public class PQMessage
{
private PQMsgPriority msgPriority;
private Object message;
#region Properties
public PQMsgPriority MsgPriority
{
get { return msgPriority; }
set { msgPriority = value; }
}
public Object Message
{
get { return message; }
set { message = value; }
}
#endregion
public PQMessage(PQMsgPriority msgPriority, Object message)
{
this.msgPriority = msgPriority;
this.message = message;
}
}