如何将项目添加到队列的前面?

时间:2011-01-13 00:20:35

标签: c#

我正在创建一个Windows服务,该服务使用FileSystemWatcher监视特定文件夹以添加特定文件类型。由于Created事件与文件实际准备好被操作之间的差距,我创建了一个Queue<T>来保存需要处理的文件名。在Created事件处理程序中,该项目将添加到队列中。然后使用计时器,我定期从队列中抓取第一个项目并进行处理。如果处理失败,则将项目添加回队列,以便服务稍后可以重试处理。

这很好但我发现它有一个副作用:在重新尝试所有旧的重试项之前,新项目的第一次处理尝试不会发生。由于队列可能包含许多项目,因此我想将新项目强制到队列的前面,以便首先处理它们。但是从Queue<T> documentation开始,没有明显的方法可以将项添加到队列的前面。

我想我可以为新项目创建第二个队列,并优先处理这个项目,但只有一个队列似乎更简单。

那么有一种简单的方法可以将项目添加到队列的前面吗?

6 个答案:

答案 0 :(得分:34)

看起来你想要一个LinkedList<T>,它允许你做AddFirst()AddLast()RemoveFirst()RemoveLast()等事情。< / p>

答案 1 :(得分:7)

只需在计时器回调中使用Peek方法而不是Dequeue。 如果处理成功,则将项目出列。

答案 2 :(得分:4)

嗯,我同意CanSpice;但是,你可以:

var items = queue.ToArray();
queue.Clear();
queue.Enqueue(newFirstItem);
foreach(var item in items)
    queue.Enqueue(item);

令人讨厌的黑客,但它会起作用;)

相反,您可能会考虑添加第二个队列实例。这是您首先检查/执行的“优先级”队列。这会更清洁一些。您甚至可以创建自己的队列类来将它包装起来,并且整齐,好像;)

答案 3 :(得分:4)

听起来像你所追求的是Stack - 这是一个LIFO(后进先出)缓冲区。

答案 4 :(得分:2)

我建议使用两个队列:一个用于新项目,一个用于重试项目。在删除过程中将两个队列包装在与队列具有相同语义的单个对象中,但允许您将事物标记为进入新队列或插入时重试队列。类似的东西:

public class DoubleQueue<T>
{
    private Queue<T> NewItems = new Queue<T>();
    private Queue<T> RetryItems = new Queue<T>();

    public Enqueue(T item, bool isNew)
    {
        if (isNew)
            NewItems.Enqueue(item);
        else
            RetryItems.Enqueue(item);
    }

    public T Dequeue()
    {
        if (NewItems.Count > 0)
            return NewItems.Dequeue();
        else
            return RetryItems.Dequeue();
    }
}

当然,您需要一个Count属性来返回两个队列中的项目数。

如果您有两种以上的项目,那么就该升级到优先级队列了。

答案 5 :(得分:0)

您需要优先级队列。看看C5 Collections Library。它的IntervalHeap实现了IPriorityQueue接口。 C5集合库也非常好。

我相信您也可以在http://www.codeproject.comhttp://www.codeplex.com找到实施方案。