Предположим, что я получаю доступ к a DataTable
от нескольких потоков. Если я хочу получить доступ к конкретной строке, я подозреваю, что должен заблокировать ту операцию (я мог ошибиться об этом, но по крайней мере я знаю этот способ, которым я в безопасности):
// this is a strongly-typed table
OrdersRow row = null;
lock (orderTable.Rows.SyncRoot) {
row = orderTable.FindByOrderId(myOrderId);
}
Но затем, если я хочу обновить ту строку, должен я блокировать таблицу (или скорее таблица Rows.SyncRoot
объект) снова, или я могу просто заблокировать строку?
На самом деле, простое выполнение блокировки
в одном месте DataTable или DataRow на самом деле ничего не делает . При использовании блокировок Monitor
(а это и есть блок lock
) следует помнить о том, что блокировка объекта ничего с ним не делает; это одна из причин, по которой некоторые выступают за использование выделенных объектов блокировки вместо блокировки самого ресурса, поскольку это заставляет вас осознавать, что вы должны выполнять блокировку (и для одного и того же объекта) всякий раз, когда вы имеете дело с ресурсом.
При этом лучше заблокировать всю DataTable
, так как само хранилище данных там (объекты DataRow
внутри содержат только смещение в ) DataTable
относительно того, где получить данные). Из-за этого, даже если вы синхронизируете доступ к отдельным строкам, одновременное обновление двух разных строк приведет к тому, что вы обновите один и тот же механизм хранения данных несинхронизированным образом.
Здесь возникает конфликт между просмотром внутренних типов как «черного ящика» и блокировкой только того, что вам нужно (что, в данном случае, приведет вас к ошибочному выводу о блокировке только строки), и попыткой понять суть внутренняя работа типа и полагаясь на детали реализации , которые могут измениться .
В результате прямо сейчас вы должны заблокировать всю DataTable
, чтобы избежать несинхронизированного обновления внутренней системы хранения данных .
Таблица данных безопасна только для многопоточных операций чтения:
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
При чтении о таблице данных возникает конфликт информация о возможности заблокировать таблицу и позволяет безопасно обновлять данные в строке. По второй ссылке вы можете заблокировать таблицу и обновить строку. Поскольку это от MS MVP, я бы сказал, что вы, вероятно, можете заблокировать таблицу и все будет в порядке.
вам не нужно блокировать для чтения - только для записи / обновления. блокируйте наименьшее количество, которое вы можете, чтобы обеспечить согласованность данных... обычно только одну строку, которую вы обновляете. если вы обновляете родительские / дочерние отношения между таблицами, вам нужно блокировать каждую строку в каждой таблице.