Если я обновляю DataRow, я блокирую весь DataTable или только DataRow? - PullRequest
7 голосов
/ 09 апреля 2010

Предположим, у меня есть доступ к DataTable из нескольких потоков. Если я хочу получить доступ к определенной строке, я подозреваю, что мне нужно заблокировать эту операцию (я могу ошибаться по этому поводу, но, по крайней мере, я знаю, что таким образом я в безопасности):

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

Но затем, если я хочу обновить эту строку, я должен заблокировать таблицу (точнее, Rows.SyncRoot объект таблицы) снова или я могу просто заблокировать строка?

Ответы [ 3 ]

5 голосов
/ 09 апреля 2010

На самом деле, просто выполнение lock в одном месте в DataTable или DataRow фактически не делает ничего. При использовании Monitor блокировок (что и является блоком lock) важно помнить, что блокировка объекта ничего с ним не делает; это одна из причин, по которой некоторые рекомендуют использовать выделенные блокирующие объекты, а не блокировать сам ресурс, поскольку это заставляет вас осознать, что вы должны выполнять блокировку (и для того же объекта) всякий раз, когда вы имеете дело с ресурсом.

При этом лучше заблокировать все DataTable, так как там находится само хранилище данных (объекты DataRow внутри содержат только смещение в DataTable относительно того, где получить данные) , По этой причине, даже если вы синхронизируете доступ к отдельным строкам, одновременное обновление двух разных строк приведет к несинхронизированному обновлению одного и того же механизма хранения данных.

Здесь возникает конфликт между просмотром внутренних типов как «черным ящиком» и блокировкой только того, что вам нужно (что в данном случае приведет к ошибочному выводу о блокировке только строки) и попыткой понять внутренняя работа типа и опора на детали реализации , которые могут измениться .

В результате прямо сейчас вы должны заблокировать все DataTable, чтобы избежать несинхронизированного обновления внутренней системы хранения данных .

3 голосов
/ 09 апреля 2010

Таблица данных безопасна только для многопоточных операций чтения:

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, я бы сказал, что вы, вероятно, можете заблокировать стол и все будет в порядке.

3 голосов
/ 09 апреля 2010

вам не нужно блокировать чтение - только для записи / обновления. заблокируйте наименьшее возможное количество, чтобы обеспечить согласованность данных ... обычно только одну строку, которую вы обновляете. если вы обновляете родительские / дочерние отношения между таблицами, вам нужно заблокировать каждую строку в каждой таблице.

...