Devo bloccare un elenco di oggetti mentre un socket sta ricevendo messaggi?

2

Ho uno scenario in cui riceverò messaggi tramite una connessione socket. Devo anche tenere un elenco di 100 messaggi (come ad esempio Elenco) e rilasciare periodicamente vecchi messaggi dall'elenco quando viene soddisfatta una condizione.

List<Message> MessageList = new List<Message>();
Message CurrentMessage = new Message();

public void ReceiveSocketMessage (SocketMessage Message) {

    if (Message.Type == duplicate) {
        CurrentMessage = MessageList.FirstOrDefault(x=> x.MessageText == Message.Text);
        CurrentMessage.Time = DateTime.Now;
    } else {
        MessageList.Add(Message);
    }
}

Poiché il socket invia i messaggi molto rapidamente, sembra che qualsiasi altro metodo che tenta di accedere a MessageList causerà un problema. Altri metodi dovranno accedere all'elenco in molti punti casuali nel tempo.

Non riesco proprio a farmi girare la testa lavorando sull'elenco di oggetti senza causare problemi. Qual è il metodo tradizionale per gestirlo?

AGGIORNAMENTO: sarebbe più semplice mantenere un elenco di elementi in una tabella di database anziché un elenco di oggetti c #? Un database avrebbe sicuramente risolto tutti i principali problemi di blocco in un punto in cui non avrei dovuto preoccuparmene.

    
posta osoclever 21.01.2014 - 04:10
fonte

2 risposte

1

I tuoi fattori guida qui dovrebbero essere la quantità di traffico che ti aspetti di vedere attraverso la tua coda, quanto è importante e la relazione tra letture e scritture.

Ora ci sono alcune raccolte incorporate molto utili nel framework .Net che possono aiutarti con le cose della concorrenza e risparmiare un sacco di tempo e fatica ma, naturalmente, una volta che giochi con le risorse di blocco e sblocco, sarai quasi sicuramente prima o poi in alcune oscure circostanze di blocco. Certamente un ConcurrentQueue o simile dovrebbe essere in grado di aiutarti con il problema che hai delineato. Naturalmente le code si aspettano un tipo di flusso di lavoro push-pop, che può essere quello che vuoi ma, in caso contrario, potresti essere ben servito a cercare in altri Raccogli le raccolte sicure .

Se si tratta di messaggi in arrivo che devi essenzialmente inserire in una coda "ricevuta" e poi elaborarli, potresti cercare di utilizzare una coda di messaggi di qualche tipo piuttosto che semplicemente rilasciare i dati nel database, questo può offrirti i vantaggi di avere i tuoi dati di coda memorizzati in modo tale che se il sistema va giù dovrebbe essere recuperabile (che può o non può essere importante per te) e significa anche potenzialmente che se hai bisogno di distribuire il tuo carico di lavoro in futuro puoi semplicemente collegare altri client alla coda ed elaborarli secondo necessità. Ci sono un sacco di strumenti Message Queue che possono aiutarti, ma ovviamente la necessità di questo è piuttosto dipendente dal tuo contesto.

    
risposta data 11.02.2014 - 18:30
fonte
1

Vorrei incapsulare l'elenco standard in una classe elenco personalizzata, che deve essere reso thread-safe. Il modo in cui arriva alla sicurezza del thread è ben incapsulato e l'implementazione può essere ottimizzata per le migliori prestazioni, dato il suo utilizzo tipico.

Prima prova se un semplice blocco su ogni accesso alla lista offre prestazioni accettabili. Se è così, hai finito!

Se questo è troppo lento, dovresti profilare l'utilizzo dell'elenco. Ci sono molte letture da più thread e solo poche scritture? Si potrebbe provare ReaderWriterLock, che consentirebbe alle letture di essere in parallelo. E forse un po 'di buffering per fare un aggiornamento di massa, che riduce al minimo il tempo di blocco della scrittura.

    
risposta data 11.02.2014 - 17:20
fonte

Leggi altre domande sui tag