2012-09-12 22 views
5

Tôi đã có một số mã tôi hiện đang có trong một lớp tĩnh/phương pháp, nhưng tôi muốn kiểm tra xem nó có an toàn không. Từ những gì tôi đã đọc Tôi nghĩ rằng điều này nên được ok, nhưng một cái gì đó trong tâm trí của tôi là nói rằng nó có thể không được. Giai đoạn xử lý dữ liệu của trang web của tôi sử dụng dịch vụ web bên ngoài để tạo hồ sơ đặt hàng và điều này có thể khá chậm: có thể 30-40 giây, có thể là 5 hoặc 10 phút (điều này nằm ngoài tầm tay của tôi). một trang trở lại cho người dùng, sau đó bắt đầu một chuỗi mới và sau đó gửi email cho người dùng khi quá trình xử lý hoàn tất. Đây là một lớp/phương thức tĩnh. Cung cấp tất cả các đối tượng của tôi được tạo ra trong phương thức cụ thể (ngoài các giá trị mặc định của hệ thống, mà sẽ là phổ biến) phương thức đó phải là an toàn luồng, phải không. Vì vậy, ví dụ, nếu tôi cóĐảm bảo an toàn chủ đề trên phương pháp tĩnh Trong C#

public static class ProcessOrder() 
{ 
    public static int GetOrderMaxSize() 
    { 
     return (....gets and parses ConfigurationManager.AppSettings["MaxOrderSize"]...); 
    } 

    public static bool CreateOrder(Order order) 
    { 
     XmlDocument xmlDoc = GetOrderXML(order); 
     bool check = false; 
     using (CreateOrderXML.Create xmlCo = new CreateOrderXML.Create()) 
     { 
      xmlCo.Timeout = 60000; 
      System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); 

      string xmlString = ""; 
      using (StringWriter stringWriter = new StringWriter()) 
      { 
       using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter)) 
       { 
        xmlDoc.WriteTo(xmlWriter); 
        xmlWriter.Flush(); 
        xmlString = stringWriter.GetStringBuilder().ToString(); 
       } 
      } 

      byte[] bXMLOrder = encoding.GetBytes(xmlString); 
      byte[] breturnMessage; 

      check = xmlCo.Create(bXMLOrder, out breturnMessage); 
      .... do something with return message 
     } 
     return check; 
    } 

    private static XmlDocument GetOrderXML(Order order) 
    { 
     ... creates an XML object for the order 
    } 
} 

(các CreateOrderXML là một tài liệu tham khảo phục vụ cho URL Web Service/phương pháp) đó sẽ là thread-an toàn, đặc biệt là trong thời gian dài chạy (chủ yếu tại xmlCo.Create (....) giai đoạn) chủ đề đồng thời? Tôi hiểu rằng nếu tôi bắt đầu đưa vào các thành viên của lớp và sau đó sử dụng chúng trong phương pháp, điều này chắc chắn sẽ giới thiệu một vấn đề với các chủ đề khác nhau ghi đè các giá trị, nhưng miễn là các đối tượng được tạo trong các phương thức, chúng sẽ ổn, t họ?

Trả lời

12

Có vẻ như bạn đang truy cập vào bất kỳ dữ liệu được chia sẻ nào ở đó; bạn đang yêu cầu tài nguyên từ xa và xây dựng một bộ dữ liệu duy nhất với mỗi lần thực thi phương pháp này. Không cần đồng bộ hóa ở đó.

Mỗi lần thực thi phương pháp ở đây là tạo các biến cục bộ - đó là các bản sao riêng. Vì vậy, không có gì là bao giờ được chia sẻ.

+0

Có, tôi đã cố ý chỉ sử dụng các biến "mặc định toàn hệ thống" trong lớp và tôi chuyển mọi thứ cần thiết cho quá trình xử lý có thể dành riêng cho người dùng/phiên trong thông số của phương thức. Nhưng tôi vẫn có những tiếng còi cảnh báo xuất hiện ở phía sau đầu, hy vọng chúng chỉ là "hoang tưởng lành mạnh". –

+0

Nghe như hoang tưởng khỏe mạnh với tôi! –

5

Nếu phương pháp tĩnh của bạn không truy cập bất kỳ dữ liệu tĩnh nào (lớp), nó phải an toàn chỉ. Điểm tranh chấp duy nhất có thể là các tài nguyên bên ngoài mà nó có thể sử dụng (các tệp, ví dụ hoặc các tài nguyên hệ thống khác) và dữ liệu được truyền vào. Và chỉ bạn biết bối cảnh của loại sử dụng đó.

Việc sử dụng những thứ như thế có thể bị tranh chấp có thể được tuần tự hóa với số lock hoặc các thành phần nguyên thủy khác. Đừng quên tuần tự hóa các tài nguyên theo cùng một thứ tự vì sợ bạn bế tắc. Nếu bạn có một phương pháp có sử dụng tài nguyên A và B:

lock(latch_a) 
{ 
    process(object_a) ; 
    lock (latch_b) 
    { 
    process(object_a,object_b) ; 
    } 
} 

và một phương pháp mà không nghịch đảo:

lock(latch_b) 
{ 
    process(object_b) ; 
    lock (latch_a) 
    { 
    process(object_a,object_b) ; 
    } 
} 

Tại một số điểm hai bài của bạn sẽ bế tắc, khi mỗi người trong số họ đòi hỏi một nguồn tài nguyên các nhu cầu khác có thể từ bỏ quyền truy cập vào tài nguyên đã nói.

Đã chỉnh sửa để ghi chú: Xem tài liệu C# để biết chi tiết lock. Nói chung, đối tượng bị khóa đại diện (và có thể là) quyền truy cập tài nguyên được chia sẻ mà đang được tuần tự hóa. Một mẫu phổ biến là làm một cái gì đó như:

class Widget 
{ 
    private static readonly object X = new object() ; 

    public void Foo() 
    { 
    lock(X) 
    { 
     // Do work using shared resource 
    } 
    return ; 
    } 

} 
+0

Các đối tượng latch_a và latch_b có cần được tạo một lần và sau đó được truyền vào từng cuộc gọi đến phương thức tĩnh không? – Doug

+0

@Doug: Xem câu trả lời đã sửa đổi của tôi. –

Các vấn đề liên quan