假设我正在从多个线程访问DataTable
。如果我想访问一个特定的行,我怀疑我需要锁定该操作(我可能会误解这个,但至少我知道这样我是安全的):
// this is a strongly-typed table
OrdersRow row = null;
lock (orderTable.Rows.SyncRoot) {
row = orderTable.FindByOrderId(myOrderId);
}
但是,如果我想更新该行,我应该锁定表格(或者更确切地说,表格的Rows.SyncRoot
对象)再次,还是可以我只是锁定了行?
答案 0 :(得分:5)
实际上,只在DataTable或DataRow上的一个位置执行lock
实际上并不做任何事情。使用Monitor
锁定(这是一个lock
块)时要记住的一个重要方面是锁定一个对象不会对它做任何事情;这是一些人提倡使用专用锁定对象而不是锁定资源本身的原因之一,因为它会迫使您意识到在处理资源时必须执行锁定(并在同一个对象上)。
话虽这么说,锁定整个DataTable
更好一点,因为数据存储本身就在那里(DataRow
对象内部只包含DataTable
的偏移量。在哪里检索数据)。因此,即使您同步对各个行的访问,同时更新两个不同的行也会导致您以非同步方式更新相同的数据存储机制。
在将内部类型视为“黑匣子”并仅锁定您需要的内容(在这种情况下,会导致您只能锁定行的错误结论)并尝试深入了解之间存在冲突该类型的内部工作方式,并依赖于可能更改的实现细节。
结果是,您现在应锁定整个DataTable
以避免以非同步方式更新内部数据存储系统。
答案 1 :(得分:3)
您不需要锁定读取 - 仅用于写入/更新。锁定尽可能少的数量,以确保数据的一致性......通常只是您要更新的一行。如果要更新表之间的父/子关系,则需要锁定每个表中的每一行。
答案 2 :(得分:3)
数据表仅对多线程读取操作安全:
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,我会说你可能会锁定桌子并且没问题。