简体   繁体   English

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

[英]Delay Queue in C# using System.Threading.Timer

I have to implement a Delay Queue in C# as there is no standard implementation of delay queue present in the C#. 我必须在C#中实现一个延迟队列,因为C#中没有标准的延迟队列实现。 I am looking to use System.Threading.Timer for implementing delayed enqueue of a node. 我希望使用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);
    }

    .
    .
    .
}

This approach looks fine to me but since I am new to C#(from C background), I want someones opinion that whether it is the right way or are there any better and more effective methods of doing the same? 这种方法对我来说很好,但由于我是C#的新手(来自C背景),我想有人认为它是正确的方式还是有更好更有效的方法做同样的事情?

I don't think that creating timers for each item is a good idea. 我不认为为每个项目创建计时器是个好主意。 Anyway, you only need to get first ready item when you dequeue item from queue, then you just can store time when item will be ready: 无论如何,当您从队列中将项目从队列中取出时,您只需要获得第一个就绪项目,然后您可以在项目准备就绪时存储时间:

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 (blocking queue with waiting timeout) 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);
}

Usage: 用法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM