我必须在C#中实现一个延迟队列,因为C#中没有标准的延迟队列实现。我希望使用System.Threading.Timer
来实现节点的延迟入队。
public class DelayQueue<T>
{
private Queue queue<T> = new Queue<T>();
public void Enqueue(Object object)
{
this.queue.Enqueue(object as T);
}
public void Enqueue(T node, TimeSpan dueTime)
{
new System.Threading.Timer(this.Enqueue, node, dueTime, -1);
}
.
.
.
}
这种方法对我来说很好,但由于我是C#的新手(来自C背景),我希望有人认为这是正确的方式还是有更好更有效的方法呢?
答案 0 :(得分:4)
我不认为为每个项目创建计时器是个好主意。无论如何,当您从队列中将项目从队列中取出时,您只需要获得第一个就绪项目,然后您就可以存储项目准备就绪的时间:
public class DelayQueue<T>
{
private List<DelayQueueItem<T>> items = new List<DelayQueueItem<T>>();
public void Enqueue(T item)
{
Enqueue(item, TimeSpan.Zero);
}
public void Enqueue(T item, TimeSpan delay)
{
items.Add(new DelayQueueItem<T>()
{
Value = item,
ReadyTime = DateTime.Now.Add(delay)
});
}
public T Dequeue()
{
DateTime now = DateTime.Now;
var item = items.FirstOrDefault(i => i.ReadyTime <= now);
if (item != null)
{
items.Remove(item);
return item.Value;
}
return default(T);
}
private class DelayQueueItem<T>
{
public T Value { get; set; }
public DateTime ReadyTime { get; set; }
}
}
UPDATE(阻塞队列等待超时)
public T Dequeue()
{
return Dequeue(TimeSpan.Zero);
}
public T Dequeue(TimeSpan timeout)
{
DateTime startTime = DateTime.Now;
do
{
DateTime now = DateTime.Now;
var item = items.FirstOrDefault(i => i.ReadyTime <= now);
if (item == null)
continue;
items.Remove(item);
return item.Value;
}
while (DateTime.Now - startTime < timeout);
return default(T);
}
用法:
DelayQueue<string> queue = new DelayQueue<string>();
queue.Enqueue("world", new TimeSpan(0, 0, 1));
queue.Enqueue("hello");
queue.Enqueue(",");
TimeSpan timeout = new TimeSpan(0, 0, 2);
Console.WriteLine(queue.Dequeue());
Console.WriteLine(queue.Dequeue(timeout));
Console.WriteLine(queue.Dequeue(timeout));