问题
I'm trying to figure out what data type to use... Basically I want a FIFO queue that is thread-safe and will automatically throw out old enough items once it gets to a pre-specified limit.
Well, actually, maybe more of a list, because I don't want the whole concept of pushing onto the queue and popping an item off the queue at which point it's no longer available.
The use case is basically for a playlist where I would have up to 5 upcoming items, the currently playing item, and then about 20 items that have already played. Hence, why I guess it cannot be a queue, I would be accessing one of the items in the middle as the "current" item. And I would rather not have to manually manage throwing away old items when the list gets to big... obviously I could write this all myself, but I don't want to reinvent the wheel if this already exists for C#.
Any ideas of what I could use?
回答1:
In the Framework there is something almost having the functionality you want - the ConcurrentQueue . It is thread-safe queue with most operations being implemented lock-free, so it is very fast.
The only function is does not have is the "limit" with automatic "throw-away"...
But that can be easily added - just create you own class containing a private ConcurrentQueue and implement the "throw-away part" in your public enqueue method by Dequeuing/throwing away till your limit is satisfied before Enqueuing the new element.
EDIT - as per comment:
One option would be to make the second "Queue" an ObservableCollection - though not inherently thread-safe (beware) this would be easily bind in WPF...
Another would be to make your class implement the ObservableCollection interface (which consists of IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable, INotifyCollectionChanged, INotifyPropertyChanged) accordingly - that sounds alot, but most of these you get easily implemented by relaying to the internal ConcurrentQueue so there is not much real code to write...
See http://msdn.microsoft.com/en-us/library/ms752347.aspx
回答2:
You might try new ReplaySubject<T>(int count) from Rx, which buffers the last count objects from the stream of observed events.
http://msdn.microsoft.com/en-us/library/hh229429.aspx
If you need a more conventional programming model (Rx is a little out there) then maybe try TPL DataFlow BroadcastBlock<T>. Broadcast is named as in TV broadcast - if a frame isn't 'processed' fast enough it is dropped, so processing stays relevant with respect 'live' frame.
http://msdn.microsoft.com/en-us/library/hh160447.aspx
UPDATE: ReplaySubject replays the first X, it is not a FIFO queue it is a 'First X List'.
来源:https://stackoverflow.com/questions/7142247/threadsafe-fifo-list-with-automatic-size-limit-management