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