简体   繁体   English

线程安全缓冲的可观察优先级队列?

[英]Thread-Safe Buffered Observable Priority Queue?

I'm writing a program where one thread needs to push items onto the queue, and one or more threads pops items off the queue and processes them. 我正在编写一个程序,其中一个线程需要将项目推送到队列中,并且一个或多个线程将项目从队列中弹出并处理它们。 To avoid running out of memory, I'd like the producer thread to sleep when the queue gets full. 为了避免内存不足,我希望生产者线程在队列变满时休眠。 Some items have a higher priority than others, so I'd like those to be processed first. 有些项目的优先级高于其他项目,所以我希望首先处理这些项目。 If the items have the same priority, I'd like the one that was added first to be processed first. 如果项目具有相同的优先级,我希望首先添加的项目首先被处理。

I want to display the top 100 items or so in a WPF DataGrid, so it needs to be accessed by a UI thread as well. 我想在WPF DataGrid中显示前100个项目,因此它也需要由UI线程访问。 Would be nice if it could notify the UI thread that there's been an update as well, ie, implements IObservable. 如果它可以通知UI线程也有更新,即实现IObservable,那将会很好。

Is there a container class that will do all this? 是否有容器类可以完成所有这些操作?

For bonus points, I'm pretty sure the entire queue doesn't need to be locked both when enqueing and dequeing. 对于奖励积分,我很确定在排队和出队时都不需要锁定整个队列。

.NET 4 implementations are fine. .NET 4实现很好。

You are out of luck looking for a container - you have to implement one yourself. 你运气不好寻找容器 - 你必须自己实施一个容器。 Be carefull with priorities - sorting gets slow fast. 小心优先级 - 排序速度很慢。 What I do is I have a queue class implemented myself that internally uses multiple arrays (one per priority - coded low, middle, high). 我所做的是我自己实现了一个队列类,内部使用多个数组(每个优先级一个 - 编码低,中,高)。 This way I never sort. 这样我从不排序。 Avoid locks if you can (multi core assumed) and go for Spinlocks (.NET 4.0), they are faster / carry less overhead in a queue scenario. 如果可以,请避免使用锁(假设为多核)并使用自旋锁(.NET 4.0),它们在队列方案中更快/更少开销。

If you're on .NET 4 you should seriously consider the Task Parallel Library with a custom scheduler like the example QueuedTaskScheduler . 如果您使用的是.NET 4,则应该认真考虑使用自定义调度程序的任务并行库 ,例如QueuedTaskScheduler示例。 I'm not sure it meets all your requirements, but it would be a good start. 我不确定它是否满足您的所有要求,但这将是一个良好的开端。

What I've done in the past is wrapped multiple ConcurrentQueue<T> collections into one -- sort of what TomTom suggests . 我过去所做的是将多个ConcurrentQueue<T>集合包装成一个 - 这是TomTom所建议的 This is pretty reasonable when the number of priorities you intend to have is low. 当您打算拥有的优先级数量很少时,这是非常合理的。 For instance in some cases it may even be sufficient to have two: high and low. 例如,在某些情况下,甚至可能有两个:高和低。 Then your TryDequeue method just looks something like this: 然后你的TryDequeue方法看起来像这样:

public bool TryDequeue(out T item)
{
    return _highItems.TryDequeue(out item) || _lowItems.TryDequeue(out item);
}

This isn't exactly a comprehensive answer to your question, but maybe it can help you get started. 这不是您问题的全面答案,但也许它可以帮助您入门。

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

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