Ho letto sull'elemento syncroot ma non riesco a trovarlo nel tipo Elenco. Quindi, come deve essere eseguita la sincronizzazione del multithreading con il file System.Collections.Generic.List <>?È corretto bloccare System.Collections.Generic.List <t>?
risposta
Il motivo per cui non riesci a trovarlo è perché era explicitly removed. Se è davvero quello che vuoi fare, usa un SynchronizedCollection<T>
o crea un oggetto di sincronizzazione dedicato. L'approccio migliore (in generale) è creare un oggetto di sincronizzazione dedicato, come illustrato da Winston.
Il problema essenziale con la proprietà SyncRoot
è che fornisce un falso senso di sicurezza - gestisce solo un insieme molto ristretto di circostanze. Gli sviluppatori spesso trascurano la sincronizzazione per un'intera operazione logica, presupponendo che il blocco su SyncRoot
sia sufficiente.
Generalmente si desidera evitare il blocco su un tipo (List<T>
in questo caso). Se, ad esempio, hai due istanze del tuo tipo, o un altro tipo dovresti utilizzare anche un blocco su List<T>
, sarebbero tutti in competizione per un unico blocco globale. In realtà, quello che stai cercando di ottenere è la sincronizzazione corretta per un singolo oggetto.
Dai un'occhiata a here ("Raccolte simultanee in C#").
si deve lanciare la lista generica a un ICollection
come questo:
using System.Collection; // required for ICollection
using System.Collection.Generic;
List<int> myIntList = new List<int>();
lock (((ICollection)myIntList).SyncRoot)
{
// do your synchronized stuff here...
}
Tenete a mente che questo sincronizza solo l'accesso agli elementi della lista generica. È non sincronizzare l'accesso alla variabile di lista generica, ad esempio myIntList
. Se si sostituisce myIntList
con un nuovo elenco a un certo punto, utilizzare SyncRoot
non sarà sufficiente. In tal caso, suggerirei di creare un oggetto di sincronizzazione specifico che può essere utilizzato per entrambi gli scenari di sincronizzazione.
Perché si desidera bloccare List<T>
in contrasto con l'istanza specifica di un elenco?
Spesso si suggerisce che il metodo migliore per bloccare sia bloccare un oggetto privato creato esclusivamente per tale scopo.
private readonly object myListLock = new object();
// Everywhere you access myList
lock(myListLock)
{
// do stuff with myList
}
Per una grande guida per la filettatura in C#, vedere questo Free E-Book (Threading in C#) da Joe Albahari.
Non penso che voglia bloccare 'Lista
Infatti, questo è quello che ha detto il suo post. Ma il titolo mi porta a credere che stava prendendo in considerazione il blocco su List
Perché è meglio che bloccarsi sull'istanza della lista? – foson
La risposta è sì, è possibile utilizzare un'istanza della lista come un oggetto di sincronizzazione:
private readonly List<string> list = new List<string>();
lock(list)
{
// ...
}
Quindi non c'è bisogno di utilizzare la proprietà SyncRoot. Inoltre, afferma che documentation
Per le collezioni il cui negozio di fondo non è a disposizione del pubblico, l'attuazione prevista è quello di restituire l'istanza corrente.
, ad esempio in alcuni casi la proprietà SyncRoot restituisce l'oggetto stesso.
Leggere anche this answer su SyncRoot.
FYI: Non ho mai visto gli usi di SyncRoot nel codice di produzione. Quindi io suggerisco di utilizzare l'istanza di qualsiasi raccolta come oggetto di sincronizzazione invece della sua proprietà SyncRoot (purché la raccolta sia privata).
- 1. Come utilizzare l'espressione del generatore CMake $ <TARGET_FILE: tgt>?
- 2. Qual è il modo corretto per bloccare zone di codice
- 3. proprietà Accesso su System.Collections.Generic.List
- 4. Conte di System.Collections.Generic.List
- 5. C# System.Collections.Generic.List`1 [System.String]
- 6. Impossibile convertire implicitamente il tipo 'System.Collections.Generic.IEnumerable <AnonymousType # 1>' a 'System.Collections.Generic.List <modelClass>
- 7. È corretto questo semplice programma C++ utilizzando <locale>?
- 8. Bloccare correttamente un elenco <T> in scenari multithreading?
- 9. Impossibile convertire implicitamente il tipo 'int' a 'System.Collections.Generic.List <QuickTest.Stock>'
- 10. Impossibile convertire implicitamente il tipo 'stringa' in 'System.Collections.Generic.List <string>'
- 11. Uso corretto (s) di const_cast <>
- 12. L'utilizzo del tipo generico 'System.Collections.Generic.List <T>' richiede argomenti tipo '1'
- 13. Nel codice HTML corretto, è necessario un <input> in un <form>?
- 14. System.Collections.Generic.List non contiene una definizione per 'selezionare'
- 15. Corretto costante e <random>
- 16. C# per bloccare o non bloccare
- 17. Qual è il nome dell'operatore "<<<"?
- 18. È possibile bloccare gli SMS in uscita?
- 19. Perché $ {0x0} è corretto?
- 20. - Qual è l'approccio corretto?
- 21. Il ricondizionatore è corretto?
- 22. Django: limit_choices_to (è corretto)
- 23. <% $, <% @, <% =, <% # ... qual è il problema?
- 24. Impossibile copiare una std :: vector <std :: function <void()>> utilizzando l'inizializzazione uniforme. È corretto?
- 25. Funzioni "amico" e << overloading dell'operatore: qual è il modo corretto di sovraccaricare un operatore per una classe?
- 26. Modo corretto per includere i CSS dopo <head>
- 27. Rhino Mocks - Uso corretto di Arg <T> .Ref
- 28. C# è questo disegno "corretto"?
- 29. È corretto chiamare java.lang.String immutabile?
- 30. È corretto derivare da System.ArgumentException?
beh so che il codice Elenco theList; lock (theList.SyncRoot) {} ma il problema è che non posso ottenere l'elemento SyncRoot da mostrare sulla mia collezione –
Karim