2010-04-09 9 views
7

Giả sử tôi đang truy cập DataTable từ nhiều chuỗi. Nếu tôi muốn truy cập vào một hàng cụ thể, tôi nghi ngờ tôi cần phải khóa mà hoạt động (tôi có thể bị nhầm lẫn về điều này, nhưng ít nhất tôi biết cách này tôi là an toàn):Nếu tôi đang cập nhật DataRow, tôi có khóa toàn bộ DataTable hay chỉ DataRow không?

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

Nhưng sau đó, nếu tôi muốn cập nhật hàng đó, tôi có nên khóa bàn (hay đúng hơn là đối tượng Rows.SyncRoot của bảng) lần nữa hoặc tôi có thể chỉ khóa hàng?

Trả lời

5

Thực ra, chỉ cần thực hiện lock ở một nơi trên DataTable hoặc DataRow không thực sự là làm bất kỳ thứ gì. Một khía cạnh quan trọng cần nhớ khi sử dụng khóa Monitor (đó là khối lock) là khóa một đối tượng không làm gì với nó; đó là một lý do mà một số người ủng hộ sử dụng các đối tượng khóa chuyên dụng hơn là khóa tài nguyên, vì nó buộc bạn phải nhận ra rằng bạn phải thực hiện khóa (và trên cùng một đối tượng) bất cứ khi nào bạn xử lý tài nguyên.

Điều đó đang được nói, tốt hơn nên khóa toàn bộ DataTable, vì bản thân lưu trữ dữ liệu ở đó (các đối tượng DataRow nội bộ chỉ chứa bù đắp vào DataTable về nơi để truy xuất dữ liệu). Vì điều này, ngay cả khi bạn đồng bộ hóa quyền truy cập vào các hàng riêng lẻ, việc cập nhật hai hàng khác nhau đồng thời sẽ khiến bạn cập nhật cùng một cơ chế lưu trữ dữ liệu theo cách không đồng bộ. Có một cuộc xung đột ở đây giữa việc xem các loại nội bộ dưới dạng "hộp đen" và chỉ khóa những gì bạn cần (trong trường hợp này, sẽ dẫn bạn đến một kết luận bị lỗi khi chỉ khóa hàng) và cố gắng có được thông tin chi tiết vào các hoạt động nội bộ của loại và dựa vào chi tiết triển khai có thể thay đổi.

Kết quả là, ngay bây giờ, bạn nên khóa toàn bộ DataTable để tránh cập nhật hệ thống lưu trữ dữ liệu nội bộ theo cách không đồng bộ.

+0

Câu trả lời rất sâu sắc, và tôi có thể thấy lý do tại sao bạn cảm thấy cần phải chỉ ra cơ chế 'khóa' hoạt động như thế nào ... Tôi đã nhận ra rằng khóa không làm bất kỳ thứ nào * thành * một đối tượng; Tôi cho rằng một cách tốt hơn tôi có thể đặt ra câu hỏi của mình là "Tôi có cần phải đồng bộ hóa các hoạt động cập nhật cho mỗi hàng hoặc mỗi bảng không?" Trong mọi trường hợp, rõ ràng với tôi vào thời điểm này, tôi phải đồng bộ hóa các cập nhật cho * bất kỳ * hàng nào trên toàn bộ bảng - cho dù bằng cách khóa bảng hay "khóa bàn" chuyên dụng (trong trường hợp này, tôi nghĩ là hàng 'Rows '). Đối tượng SyncRoot' phục vụ mục đích đó, thực sự). –

3

bạn không cần phải khóa để đọc - chỉ để viết/cập nhật. khóa số tiền nhỏ nhất mà bạn có thể, để đảm bảo tính nhất quán của dữ liệu ... thường chỉ là một hàng mà bạn đang cập nhật. nếu bạn đang cập nhật mối quan hệ cha/con giữa các bảng, bạn sẽ cần phải khóa mỗi hàng trong mỗi bảng.

+0

Liên kết được cung cấp bởi Kevin (http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/11b69e1a-ad6c-48d5-8e14-264af5b0692e) dường như chỉ ra rằng việc khóa bảng là cần thiết, thực sự. Đại diện của MSFT nói: "Giả sử rằng việc cập nhật một hàng sẽ không ảnh hưởng đến bất kỳ thứ gì khác trong bảng là nguy hiểm khi bạn dựa vào chi tiết triển khai tiềm năng có thể dễ dàng bị hỏng vào một ngày sau đó". Bạn có bất kỳ thông tin chi tiết nào về việc điều này có đúng không? –

3

Các DataTable chỉ an toàn cho ren đa các hoạt động đọc:

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

On đọc về DataTable có thông tin mâu thuẫn liên quan đến khả năng khóa bàn và cho phép bạn một cách an toàn cập nhật dữ liệu liên tiếp. Theo liên kết thứ hai, bạn có thể khóa bảng và cập nhật hàng. Là đây là từ một MVP MS, tôi sẽ nói rằng bạn có thể có thể khóa bảng và được ok.

+1

Liên kết nói: "Loại này an toàn cho hoạt động đọc đa luồng. Bạn phải đồng bộ hóa bất kỳ thao tác ghi nào" Điều này không có nghĩa là khóa là điều đúng để thực hiện truy cập đa luồng? – code4life

+0

Tôi đang bối rối; liên kết đầu tiên bạn cung cấp dường như nói rằng bạn chỉ cần khóa viết (mặc dù nó không nói * những gì * để khóa). Thứ hai dường như chỉ ra rằng khóa bảng là cách tiếp cận chính xác. Dường như không đồng ý với tuyên bố của bạn rằng bạn không thể khóa bàn và mong đợi các lần đọc nhất quán. Tui bỏ lỡ điều gì vậy? –

+0

Phát biểu đầu tiên của tôi không chính xác. Tôi đã tìm thấy thông tin xung đột. Bạn không cần phải khóa bảng để đọc dữ liệu như vậy là ok. Bạn cần khóa bảng để ghi dữ liệu. – kemiller2002