Sto cercando di aggiornare le voci in un qualcosa di ConcurrentDictionary come questo:Aggiornamento campi di valori in una ConcurrentDictionary
class Class1
{
public int Counter { get; set; }
}
class Test
{
private ConcurrentDictionary<int, Class1> dict =
new ConcurrentDictionary<int, Class1>();
public void TestIt()
{
foreach (var foo in dict)
{
foo.Value.Counter = foo.Value.Counter + 1; // Simplified example
}
}
}
In sostanza ho bisogno di iterare il dizionario e aggiornare un campo su ogni valore. Capisco dalla documentazione che devo evitare di usare la proprietà Value. Invece penso che ho bisogno di usare TryUpdate tranne che non voglio sostituire il mio intero oggetto. Invece, voglio aggiornare un campo sull'oggetto.
Dopo aver letto this blog entry sul blog del team PFX: Forse ho bisogno di utilizzare AddOrUpdate e semplicemente non fare nulla nell'aggiunta delegato.
Qualcuno ha qualche idea su come farlo?
Ho decine di migliaia di oggetti nel dizionario che devo aggiornare ogni trenta secondi circa. La creazione di nuovi per aggiornare la proprietà probabilmente non è fattibile. Avrei bisogno di clonare l'oggetto esistente, aggiornarlo e sostituire quello nel dizionario. Avrei anche bisogno di bloccarlo per la durata del ciclo clone/add. Che schifo.
Quello che mi piacerebbe fare è iterare sugli oggetti e aggiornare la proprietà Contatore direttamente se possibile.
Le mie ultime ricerche mi hanno portato a Parallel.ForOgni che suona bene ma non dovrebbe essere usato per azioni che aggiornano lo stato.
Ho anche visto menzionare Interlocked.Increment che suona alla grande ma ho ancora bisogno di capire come usarlo su ogni elemento nel mio dizionario in modo thread-safe.
c'è in realtà alcuna concorrenza succede se sempre e solo aggiorna un campo di ogni valore ogni 30 secondi? Sembra un normale dizionario e un ciclo foreach dovrebbe essere tutto ciò di cui hai bisogno. Parallel.ForEach dovrebbe funzionare anche perché non ci sono risorse condivise. – dtb
Mentre il thread di aggiornamento è in esecuzione, gli oggetti aggiuntivi verranno aggiunti e rimossi dal dizionario da altri thread. Inoltre, altre proprietà sull'oggetto verranno aggiornate tramite altri thread in risposta ai messaggi WCF. Quindi sì, c'è un sacco di concorrenza in corso. Grazie per l'aiuto! – rboarman
OK. Quindi la mia risposta persiste. Utilizzare AddOrUpdate/GetOrAdd/TryUpdate ecc per manipolare il contenuto del dizionario; fare un'istantanea del dizionario quando lo itera; bloccare le singole istanze di Class1 quando si cambiano le loro proprietà. – dtb