He estado leyendo sobre el elemento syncroot pero no puedo encontrarlo en el tipo de lista. Entonces, ¿cómo se debe hacer la sincronización multiproceso con System.Collections.Generic.List <> type?¿Está bien bloquear en System.Collections.Generic.List <t>?
Respuesta
La razón por la que no puede encontrarlo es porque era explicitly removed. Si es realmente lo que quiere hacer, use un SynchronizedCollection<T>
o cree un objeto de sincronización dedicado. El mejor enfoque (en general) es crear un objeto de sincronización dedicado, como lo ilustra Winston.
El problema esencial con la propiedad SyncRoot
es que proporciona una falsa sensación de seguridad: solo maneja un conjunto muy limitado de circunstancias. Los desarrolladores a menudo descuidan la sincronización de toda una operación lógica, suponiendo que el bloqueo en SyncRoot
es suficiente.
Por lo general, desea evitar el bloqueo en un tipo (List<T>
en este caso). Si, por ejemplo, tiene dos instancias de su tipo u otro tipo que también usa un candado en List<T>
, todos competirían por un único bloqueo global. Realmente, lo que estás tratando de lograr es una sincronización adecuada para un solo objeto.
Echa un vistazo here ("Colecciones concurrentes en C#").
tienen que desechar la lista genérica a un ICollection
así:
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...
}
Tenga en cuenta que esto sólo se sincroniza el acceso a los elementos de la lista genérica. Sí no sincroniza el acceso a la variable genérica de la lista, por ejemplo, myIntList
. Si reemplaza myIntList
con una nueva lista en algún momento, usar SyncRoot
no será suficiente. En ese caso, recomendaría crear un objeto de sincronización específico que pueda usarse para ambos escenarios de sincronización.
¿Por qué desea bloquear el List<T>
en lugar de su instancia específica de una lista?
A menudo se sugiere que el mejor método de bloqueo es bloquear un objeto privado creado únicamente para ese fin.
private readonly object myListLock = new object();
// Everywhere you access myList
lock(myListLock)
{
// do stuff with myList
}
Para una gran guía para enhebrar en C#, vea este Free E-Book (Threading in C#) por Joe Albahari.
No creo que quiera bloquear 'List
De hecho, eso es lo que dijo su mensaje. Pero el título me lleva a creer que estaba considerando bloquear en la lista
¿Por qué es mejor que bloquear la instancia de la lista? – foson
La respuesta es Sí, se puede utilizar una instancia de la lista como un objeto de sincronización:
private readonly List<string> list = new List<string>();
lock(list)
{
// ...
}
Así que usted no tiene que utilizar la propiedad SyncRoot. Por otra parte, afirma que documentation
Para colecciones cuyos almacén subyacente no es públicamente disponible, el de ejecución previsto es devolver la instancia actual.
es decir, en algunos casos, la propiedad SyncRoot devuelve el objeto de recopilación.
Lea también this answer sobre SyncRoot.
FYI: Nunca he visto usos de SyncRoot en el código de producción. Entonces, sugiere que use la instancia de cualquier colección como un objeto de sincronización en lugar de su propiedad SyncRoot (siempre que la colección sea privada).
- 1. Método igual de System.Collections.Generic.List <T> ...?
- 2. ¿<input> está bien formado sin <form>?
- 3. ¿Está bien usar <input type = "tel" /> ahora?
- 4. ¿Qué tan bien respaldado está <base>? ¿Debo usarlo?
- 5. No se puede convertir implícitamente el tipo 'System.Collections.Generic.List <T>' en 'System.Linq.IQueryable <T>'
- 6. memcacheD Esto está bien?
- 7. ¿Está bien usar __doPostBack()?
- 8. ¿Está bien usar == en enumeraciones en Java?
- 9. ¿Está bien para devolver una lista interna <T> como IEnumerable <T> o ICollection <T>?
- 10. ¿Cómo ordenar un System.Collections.Generic.List en VB.Net?
- 11. ¿Está bien lanzar un java.lang.Error?
- 12. ¿Está bien omitir "devolver ninguno"?
- 13. ¿Este código está bien definido?
- 14. ¿Está bien derivar de System.ArgumentException?
- 15. ¿Este código está bien definido?
- 16. ¿Está bien con archivos binarios?
- 17. ¿Está bien aún usar tablas?
- 18. cadena [longitud()] en C++, ¿está bien?
- 19. ¿Está bien guardar mucha información en $ _SESSION?
- 20. Cadenas aleatorias en Python 2.6 (¿Está bien?)
- 21. ¿Está bien poner JavaScript en vistas parciales?
- 22. ¿Está bien usar entidades HTML en atributos?
- 23. ¿Está bien usar array [key] en PHP?
- 24. En JavaScript, ¿la asignación encadenada está bien?
- 25. ¿Está bien que devuelva IEnumerator <T>. GetEnumerator() en IEnumerator.GetEnumerator()?
- 26. ¿Está bien usar cellpadding = "2" cellspacing = "2" en <table>?
- 27. ¿<script> no está en <head> ok?
- 28. Usar el tipo genérico 'System.Collections.Generic.List <T>' requiere '1' tipo argumentos
- 29. ¿El ordenamiento std :: pair <int, std :: string> está bien definido?
- 30. ¿Está bien colocar comentarios html fuera de las etiquetas <html>?
bien sé que el código Lista theList; lock (theList.SyncRoot) {} pero el problema es que no puedo obtener el elemento SyncRoot para mostrar en mi colección –
Karim