System.Collections.Concurrent ha alcune nuove raccolte che funzionano molto bene in ambienti con multithreading. Tuttavia, sono un po 'limitati. O bloccano finché un articolo non diventa disponibile, oppure restituiscono default(T)
(metodi TryXXX).Raccolta simultanea non bloccante?
Ho bisogno di una raccolta che sia thread-safe, ma invece di bloccare il thread chiamante usa un callback per informarmi che almeno un elemento è disponibile.
La mia soluzione attuale è utilizzare BlockingCollection, ma utilizzare l'APM con un delegato per ottenere l'elemento successivo. In altre parole, creo un delegato su un metodo che è Take
dalla raccolta ed eseguo tale delega utilizzando BeginInvoke
.
Sfortunatamente, devo mantenere molto stato all'interno della mia classe per raggiungere questo obiettivo. Peggio ancora, la classe non è thread-safe; può essere utilizzato solo da un singolo thread. Sto superando il limite della manutenibilità, che preferirei non fare.
So che ci sono alcune librerie là fuori che rendono quello che sto facendo qui piuttosto semplice (credo che il Reactive Framework sia uno di questi), ma mi piacerebbe realizzare i miei obiettivi senza aggiungere alcun riferimento al di fuori della versione 4 del quadro.
Esistono schemi migliori che posso utilizzare che non richiedono riferimenti esterni che raggiungono il mio obiettivo?
tl; dr:
Ci sono dei modelli che soddisfano il requisito:
"Ho bisogno di segnalare una collezione che sono pronto per l'elemento successivo, e avere la collezione esecuzione una richiamata quando il prossimo elemento è arrivato, senza che nessun thread sia bloccato. "
Questo thread-safe? Che cosa sta bloccando l'elemento disponibile che diventa non disponibile prima che il delegato venga richiamato? E qual è il tuo obiettivo generale (ad es. Un sistema di accodamento)? –
@Adam Buon punto sul consumo dell'elemento. Il delegato prende l'oggetto rimosso dalla raccolta. Quindi l'esecuzione del delegato è bloccata finché un elemento non è 'Take'-en dalla raccolta, e quell'elemento è l'oggetto' passato a EndInvoke. L'obiettivo generale è un po 'contorto; in sostanza devo rallentare un flusso di lavoro finché l'articolo non diventa disponibile. Non è possibile bloccare l'esecuzione del flusso di lavoro, quindi semplicemente "Prendere" un oggetto non funzionerà come i blocchi di chiamata. Devo creare un segnalibro, quindi passare a un'estensione. L'estensione richiama il delegato, riprendendo il segnalibro all'interno del callback. – Will
sfortunatamente ho poca esperienza con i flussi di lavoro - prova ad aggiungere quel dettaglio alla tua domanda e potrebbe suscitare l'interesse di qualcuno :-) –