C# 中的延迟队列使用 System.Threading.Timer



我必须在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 背景)的新手,我希望有人的意见,无论是正确的方法还是有更好、更有效的方法?

我不

认为为每个项目创建计时器是一个好主意。无论如何,当您从队列中取消项目排队时,您只需要获取第一个准备好的项目,然后您就可以存储项目准备就绪的时间:

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; }
    }
}

更新(阻塞队列与等待超时)

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));

相关内容

最新更新