Thông thường, khi tôi muốn có một lớp học mà là thread-safe, tôi làm điều gì đó như sau:Đây có phải là thiết kế tốt để tạo các lớp học an toàn cho chủ đề trong C# không?
public class ThreadSafeClass
{
private readonly object theLock = new object();
private double propertyA;
public double PropertyA
{
get
{
lock (theLock)
{
return propertyA;
}
}
set
{
lock (theLock)
{
propertyA = value;
}
}
}
private double propertyB;
public double PropertyB
{
get
{
lock (theLock)
{
return propertyB;
}
}
set
{
lock (theLock)
{
propertyB = value;
}
}
}
public void SomeMethod()
{
lock (theLock)
{
PropertyA = 2.0 * PropertyB;
}
}
}
Nó hoạt động, nhưng nó là rất dài dòng. Đôi khi tôi thậm chí còn tạo ra một đối tượng khóa cho mỗi phương pháp và thuộc tính tạo ra độ chi tiết và phức tạp hơn.
Tôi biết rằng cũng có thể khóa các lớp bằng cách sử dụng thuộc tính Đồng bộ hóa nhưng tôi không chắc rằng quy mô đó như thế nào - như tôi thường mong đợi có hàng trăm nghìn, nếu không phải hàng triệu trường hợp các đối tượng. Cách tiếp cận này sẽ tạo ra một bối cảnh đồng bộ hóa cho mọi cá thể của lớp, và yêu cầu lớp được bắt nguồn từ ContextBoundObject và do đó không thể bắt nguồn từ bất cứ thứ gì khác - vì C# không cho phép thừa kế nhiều - đó là một nút show trong nhiều trường hợp.
Chỉnh sửa: Khi một số người phản hồi đã nhấn mạnh, không có thiết kế lớp an toàn cho chủ đề "bạc đạn". Tôi chỉ cố gắng hiểu nếu mẫu tôi đang sử dụng là một trong những giải pháp tốt. Tất nhiên giải pháp tốt nhất trong mọi tình huống cụ thể là vấn đề phụ thuộc. Một số câu trả lời dưới đây chứa các thiết kế thay thế cần được xem xét.
Chỉnh sửa: Hơn nữa, có nhiều định nghĩa về an toàn luồng. Ví dụ: trong triển khai của tôi ở trên, mã sau sẽ KHÔNG được an toàn theo luồng:
var myObject = new ThreadSafeClass();
myObject.PropertyA++; // NOT thread-safe
Vì vậy, định nghĩa lớp trên có phải là cách tiếp cận tốt không? Nếu không, bạn sẽ đề xuất gì cho một thiết kế có hành vi tương tự sẽ an toàn cho một loạt các ứng dụng tương tự?
Vui lòng tìm kiếm trước: http://stackoverflow.com/search?q=What+is+the+Best+Practice+for+Creating+Thread-Safe+Classes+in+C%23 –
Hm. Trong mã của bạn, bạn sử dụng cùng một đối tượng khóa để đọc cả PropertyA và PropertyB. Điều đó có nghĩa là một thread đọc PropertyA sẽ khóa một cố gắng khác để đọc PropertyB cho đến khi luồng đầu tiên hoàn tất. Đó là điều bạn muốn? Nếu đây là lớp học của tôi, tôi sẽ tạo ra một tủ khóa đọc riêng biệt cho mỗi bộ nạp và sau đó người định cư cũng phải tôn trọng khóa đó. Xem câu trả lời bên dưới. –
Tôi chỉ downvoted bạn vì không có cách nào duy nhất để tạo ra một lớp thread-safe. Bất kỳ câu trả lời nào cho câu hỏi này đều gây ra ấn tượng sai lầm cho độc giả trong tương lai. –