Đây là câu hỏi chi tiết về C#.C# thread safety with get/set
Giả sử tôi đã có một lớp học với một đối tượng, và đối tượng được bảo vệ bởi một ổ khóa:
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
return property;
}
set {
property = value;
}
}
Tôi muốn có một chủ đề bỏ phiếu để có thể truy vấn bất động sản đó. Tôi cũng muốn chuỗi cập nhật các đặc tính của đối tượng đó thỉnh thoảng và đôi khi người dùng có thể cập nhật thuộc tính đó và người dùng muốn có thể xem thuộc tính đó.
Mã sau có khóa đúng dữ liệu không?
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
lock (mLock){
return property;
}
}
set {
lock (mLock){
property = value;
}
}
}
By 'đúng', những gì tôi muốn nói là, nếu tôi muốn gọi
MyProperty.Field1 = 2;
hoặc bất cứ điều gì, lĩnh vực này sẽ bị khóa trong khi tôi làm bản cập nhật? Cài đặt được thực hiện bởi toán tử equals bên trong phạm vi của hàm 'get' hay chức năng 'get' (và do đó khóa) kết thúc trước, sau đó thiết lập, và sau đó 'set' được gọi, do đó bỏ qua khoá?
Chỉnh sửa: Vì điều này rõ ràng sẽ không thực hiện thủ thuật, điều gì sẽ xảy ra? Tôi có cần phải làm điều gì đó như:
Object mLock = new Object();
MyObject property;
public MyObject MyProperty {
get {
MyObject tmp = null;
lock (mLock){
tmp = property.Clone();
}
return tmp;
}
set {
lock (mLock){
property = value;
}
}
}
mà ít nhiều chỉ đảm bảo rằng tôi chỉ có quyền truy cập vào một bản sao, nghĩa là nếu tôi có hai chủ đề gọi là 'nhận' cùng một lúc, họ sẽ bắt đầu với cùng một giá trị của Field1 (phải không?). Có cách nào để đọc và viết khóa trên thuộc tính có ý nghĩa không? Hoặc tôi nên hạn chế bản thân mình để khóa trên các phần của các chức năng hơn là dữ liệu chính nó?
Chỉ để ví dụ này có ý nghĩa: MyObject là trình điều khiển thiết bị trả về trạng thái không đồng bộ. Tôi gửi lệnh qua cổng nối tiếp và sau đó thiết bị sẽ trả lời các lệnh đó theo thời gian ngọt ngào của riêng nó. Ngay bây giờ, tôi có một chủ đề thăm dò ý kiến của nó ("Bạn vẫn còn ở đó? Bạn có thể chấp nhận lệnh?"), Một chuỗi chờ phản hồi trên cổng nối tiếp ("Chỉ có chuỗi trạng thái 2, mọi thứ đều tốt") và sau đó là chuỗi giao diện người dùng có các lệnh khác ("Người dùng muốn bạn thực hiện việc này.") và đăng phản hồi từ trình điều khiển ("Tôi vừa làm xong, bây giờ cập nhật giao diện người dùng bằng"). Đó là lý do tại sao tôi muốn khóa chính đối tượng, thay vì các trường của đối tượng; đó sẽ là một số lượng lớn các khóa, a và b, không phải mọi thiết bị của lớp này đều có hành vi tương tự, chỉ là hành vi chung, vì vậy tôi phải viết mã nhiều hộp thoại riêng lẻ nếu tôi cá nhân hoá các khóa.
Đồng ý. Tôi đã cung cấp giải pháp mẫu cho những gì bạn đang yêu cầu để trả lời câu hỏi Singleton http://stackoverflow.com/questions/7095/is-the-c-static-constructor-thread-safe/7105#7105 – Zooba
vâng, tôi ' có lẽ sẽ đi với khóa đối tượng như bạn đã mô tả. Cảm ơn. – mmr
Điểm tốt, tuy nhiên nếu ông có một số MyProperty' được gọi là 'p' và được gọi là hai chủ đề cùng một lúc:' p = new MyObject (12) 'và' p = new MyObject (5) 'sau đó * this * truy cập sẽ được đồng bộ . Tuy nhiên thành viên 'Field1' sẽ * không * bị khóa. Tôi khá chắc chắn đây là những gì bạn đang nói, chỉ cần cố gắng để hiểu nó cho bản thân mình. – Snoopy