2010-04-09 37 views
7

Supongamos que estoy accediendo a DataTable desde varios subprocesos. Si quiero acceder a una fila en particular, sospecho que necesito para bloquear esa operación (podría ser confundido por esto, pero al menos sé que de esta manera Estoy seguro):Si estoy actualizando un DataRow, ¿bloqueo el DataTable completo o solo el DataRow?

// this is a strongly-typed table 
OrdersRow row = null; 
lock (orderTable.Rows.SyncRoot) { 
    row = orderTable.FindByOrderId(myOrderId); 
} 

Pero entonces, si yo Quiero actualizar esa fila, ¿debo bloquear la tabla (o más bien, el objeto Rows.SyncRoot de la tabla) nuevamente, o puedo simplemente bloquear la fila?

Respuesta

5

En realidad, simplemente realizar un lock en un solo lugar en el DataTable o DataRow en realidad no es hacer nada. Un aspecto importante para recordar al usar los bloqueos Monitor (que es lo que es un bloque lock) es que bloquear un objeto no le hace nada; esa es una de las razones por las que algunos defienden el uso de objetos de bloqueo dedicados en lugar de bloquear el recurso en sí, ya que lo obliga a darse cuenta de que debe realizar el bloqueo (y en el mismo objeto) cada vez que maneja el recurso.

Dicho esto, es una mejor idea para bloquear toda la DataTable, como el propio almacenamiento de datos está allí (los objetos DataRow internamente contienen solamente un desplazamiento en el DataTable en cuanto a dónde recuperar los datos). Debido a esto, incluso si sincroniza el acceso a filas individuales, la actualización simultánea de dos filas ocasionará que actualice el mismo mecanismo de almacenamiento de datos de manera no sincronizada.

Aquí hay un conflicto entre ver tipos internos como un "recuadro negro" y bloquear solo lo que necesita (que, en este caso, podría llevarlo a una conclusión errónea de solo bloquear la fila) y tratar de obtener información en el funcionamiento interno del tipo y confiando en los detalles de implementación que podrían cambiar.

El resultado es que, en este momento, debe bloquear todo el DataTable para evitar la actualización del sistema interno de almacenamiento de datos de manera no sincronizada.

+0

Respuesta muy perspicaz, y puedo ver por qué sentiste la necesidad de señalar cómo funciona el mecanismo de 'bloqueo' ... Me di cuenta de que bloquear no hace nada * a * un objeto; Supongo que una mejor manera de haber redactado mi pregunta hubiera sido "¿Necesito sincronizar las operaciones de actualización por fila o por tabla?" En cualquier caso, es claro para mí en este punto que debo sincronizar las actualizaciones a * cualquier * fila en toda la tabla, ya sea bloqueando la tabla o un "bloqueo de tabla" dedicado (en este caso, creo que las 'Filas. El objeto SyncRoot' sirve bien para ese propósito, en realidad). –

3

no necesita bloquear las lecturas, solo para escrituras/actualizaciones. bloquee la cantidad más pequeña que pueda, para garantizar la coherencia de los datos ... por lo general, solo la fila que está actualizando. si está actualizando las relaciones padre/hijo entre tablas, deberá bloquear cada fila en cada tabla.

+0

El enlace proporcionado por Kevin (http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/11b69e1a-ad6c-48d5-8e14-264af5b0692e) parece indicar que bloquear la tabla es necesario, en realidad. El representante de MSFT dice: "Asumir que la actualización de una sola fila no afectará a ninguna otra cosa en la tabla es peligroso ya que se depende de un detalle de implementación potencial que puede romperse fácilmente en una fecha posterior". ¿Tiene alguna idea de si esto es cierto o no? –

3

La tabla de datos sólo es seguro para subprocesos múltiples operaciones de lectura:

http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx

http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/11b69e1a-ad6c-48d5-8e14-264af5b0692e

Al leer acerca de la tabla de datos existe información contradictoria en relación con la capacidad de bloquear la mesa y le permitirá de forma segura actualizar datos en una fila. De acuerdo con el segundo enlace, puede bloquear la tabla y actualizar la fila. Siendo esto de un MS MVP, diría que probablemente puedas bloquear la mesa y estar bien.

+1

El enlace dice: "Este tipo es seguro para operaciones de lectura multiproceso. Debe sincronizar cualquier operación de escritura" ¿Esto no significa que un bloqueo es lo correcto para el acceso multiproceso? – code4life

+0

Estoy confundido; el primer enlace que proporcionó parece indicar que solo necesita bloquear las escrituras (aunque no dice * qué * bloquear). El segundo parece indicar que bloquear la mesa es el enfoque correcto. Ninguno de los dos parece estar de acuerdo con su afirmación de que no puede cerrar la mesa y esperar que las lecturas sean consistentes. ¿Me estoy perdiendo de algo? –

+0

Mi primera declaración fue incorrecta. Encontré información conflictiva. No es necesario bloquear la tabla para leer datos, ya que está bien. Debe bloquear la tabla para escribir datos. – kemiller2002

Cuestiones relacionadas