7

假设我正在DataTable从多个线程访问 a 。如果我想访问特定的行,我怀疑我需要锁定该操作(我可能会误会,但至少我知道这样我是安全的):

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

但是,如果我想更新该行,我应该再次锁定表(或者更确切地说,表的Rows.SyncRoot对象),还是可以简单地锁定该行?

4

3 回答 3

5

实际上,仅lock在 DataTable 或 DataRow 上的一个地方执行实际上并没有任何事情。使用Monitor锁(lock块是什么)时要记住的一个重要方面是锁定一个对象不会对它做任何事情。这就是一些人提倡使用专用锁定对象而不是锁定资源本身的原因之一,因为它迫使您意识到在处理资源时必须执行锁定(并且在同一个对象上)。

话虽这么说,锁定整个 是一个更好的主意DataTable,因为数据存储本身就在那里(DataRow对象内部仅包含DataTable关于检索数据的位置的偏移量)。正因为如此,即使您同步对单个行的访问,同时更新两个不同的行也会导致您以非同步的方式更新相同的数据存储机制。

在将内部类型视为“黑匣子”和只锁定你需要的东西(在这种情况下,这会导致你得出只锁定行的错误结论)和试图深入了解内部工作之间存在冲突类型并依赖于可能改变的实现细节。

结果是,现在,您应该锁定整个DataTable,以避免以非同步方式更新内部数据存储系统

于 2010-04-09T13:45:28.983 回答
3

您不需要锁定读取 - 仅用于写入/更新。锁定尽可能少的数量,以确保数据一致性......通常只是您正在更新的一行。如果要更新表之间的父/子关系,则需要锁定每个表中的每一行。

于 2010-04-09T13:14:00.800 回答
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,我会说您可能可以锁定桌子并没问题。

于 2010-04-09T13:15:55.523 回答