2011-08-22 13 views
5

Sto cercando di capire quale tipo di dati utilizzare ... Fondamentalmente voglio una coda FIFO che è thread-safe e getterà automaticamente gli elementi abbastanza vecchi una volta che arriva a un limite pre-specificato.Elenco FIFO ThreadSafe con gestione limiti dimensione automatica

Beh, in realtà, forse più di una lista, perché non voglio che l'intero concetto di spingere in coda e scoppiare un oggetto dalla coda, a quel punto non è più disponibile.

Il caso d'uso è fondamentalmente per una playlist in cui avrei fino a 5 elementi in arrivo, l'elemento attualmente in riproduzione, e quindi circa 20 elementi che sono già stati riprodotti. Quindi, perché suppongo che non possa essere una coda, accedo ad uno degli elementi nel mezzo come elemento "attuale". E preferirei non dover gestire manualmente buttare via vecchi oggetti quando la lista diventa grande ... ovviamente potrei scrivere tutto da solo, ma non voglio reinventare la ruota se questo esiste già per C#.

Qualche idea di cosa potrei usare?

+0

Ho fatto una domanda simile (http://stackoverflow.com/questions/17031718/how-to-limit-blockingcollection-size-but-keep-adding-new-itens-net-limited-siz), voglio la stessa cosa, un FIFO di dimensioni limitate thread-safe. Sei giunto a una buona soluzione? – Pedro77

risposta

3

Nel Framework c'è qualcosa che quasi ha la funzionalità desiderata: lo ConcurrentQueue. È una coda thread-safe con la maggior parte delle operazioni in fase di lock-free, quindi è molto veloce.

L'unica funzione è non ha è il "limite" con cambio automatico "usa e getta" ...

Ma questo può essere facilmente aggiunto - basta creare si possiede classe contenente un privato ConcurrentQueue e attuare il " parte da buttare via "nel tuo metodo di accodamento pubblico disaggregando/gettando via finché il tuo limite non è soddisfatto prima di accodare il nuovo elemento.

EDIT - come da commento:
Una possibilità sarebbe quella di fare il secondo "coda" di un ObservableCollection - anche se non intrinsecamente thread-safe (attenzione) questo sarebbe facilmente si legano in WPF ...

Un altro sarebbe fare in modo che la tua classe implementasse l'interfaccia ObservableCollection (che è costituita da IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable, INotifyCollectionChanged, INotifyPropertyChanged) - ciò suona molto, ma la maggior parte di questi si implementa facilmente inoltrandosi allo ConcurrentQueue interno, quindi non c'è molto codice reale da scrivere ...
Vedi http://msdn.microsoft.com/en-us/library/ms752347.aspx

+0

Forse per l'accesso alla parte centrale posso creare un oggetto con due code ... una che contiene gli elementi in arrivo e un'altra che è l'elenco delle voci riprodotte.Sarebbe davvero bello se riuscissi a far funzionare tutto questo con il binding WPF ... –

+0

vedi il mio EDIT per quanto riguarda DataBinding ... – Yahia

1

Si potrebbe provare new ReplaySubject<T>(int count) da Rx, che bufferizza gli ultimi oggetti count dal flusso di eventi osservati.

http://msdn.microsoft.com/en-us/library/hh229429.aspx

Se avete bisogno di un modello di programmazione più convenzionale (Rx è un po 'là fuori), poi magari provare TPL DataFlow BroadcastBlock<T>. Il broadcast viene chiamato come nella trasmissione TV - se un frame non viene "processato" abbastanza velocemente viene eliminato, quindi l'elaborazione rimane rilevante rispetto al frame "live".

http://msdn.microsoft.com/en-us/library/hh160447.aspx

UPDATE: ReplaySubject riproduce il primo X, non è un FIFO coda si tratta di una 'prima lista X'.