2013-10-09 11 views
8

Chúng tôi có một hoạt động dịch vụ web WCF được sử dụng để tạo tệp PDF. Chúng tôi đang sử dụng công cụ của bên thứ 3 để thực hiện điều đó (đặc biệt là Syncfusion) mà chúng tôi không thể thay thế vào lúc này.WCF webservice - đang sử dụng khóa sẽ gây ra sự cố?

Vấn đề là có vẻ như công cụ của bên thứ 3 có vấn đề với đa luồng và không hoạt động trong một số trường hợp khi có nhiều cuộc gọi đến dịch vụ web cùng một lúc.

Chúng ta có thể thoát khỏi vấn đề bằng cách sử dụng lock và đảm bảo rằng chỉ có một thread thực thi phần quan trọng:

Public Class GeneratorController 
{ 
    // object we use for lock 
    private static Object thisLock = new Object(); 

    public void Generate(ref PdfDocument pdfDocument) 
    { 
     lock (thisLock) 
     { 
      // critical section 
     } 
    } 
} 

Câu hỏi của tôi là: là một ý tưởng tốt? Nó sẽ gây ra bất kỳ vấn đề nào nếu chúng ta có một mã như vậy trong một dịch vụ web?

Note

Đây không phải là một câu hỏi về Syncfusion. Đây là câu hỏi về việc sử dụng lock trong dịch vụ web. Không thay đổi thẻ để đồng bộ hóa, vui lòng.

+0

Tôi không quen với Syncfusion - có thể tạo nhiều bản sao đồng thời của đối tượng không? Tôi sẽ nghĩ nếu bạn có những trường hợp riêng biệt, bạn sẽ không cần phải khóa. – Tim

+0

Tôi mặc dù vậy quá nhưng nó có vẻ là vấn đề. Có thể họ đang sử dụng thứ gì đó tĩnh trong mã của họ ... – Szymon

Trả lời

4

WCF hỗ trợ gọi điện thoại đồng bộ của các đối tượng dịch vụ của bạn, tùy thuộc vào nhu cầu của bạn, bạn có thể muốn nhìn vào hai thuộc tính sau:

Nếu bạn không thể khởi chạy nhiều phiên bản của thành phần bên thứ 3 và thành phần không cho phép conc acccess urrent (trường hợp xấu nhất), sau đó bạn có thể chỉ định InstanceContextMode = Single, và ConcurrencyMode = Single; Trong trường hợp này, WCF sẽ chỉ khởi tạo một bản sao của đối tượng WCF của bạn (mà tôi giả định là một trình bao bọc xung quanh thành phần của bên thứ 3) và chỉ một yêu cầu được xử lý tại một thời điểm. Các yêu cầu sẽ được xếp hàng đợi và xử lý theo cách thức FIFO. Bạn không cần phải sử dụng khóa bên trong dịch vụ wcf của bạn, vì thời gian chạy WCF đảm bảo rằng bạn có quyền truy cập đồng bộ vào các đối tượng wcf của mình.

7

Vấn đề tôi thấy ở đây là nạn đói tài nguyên.

Không có khóa quy tắc FIFO xung quanh. Vì vậy, nếu có một tải liên tục, bạn có thể nhận được kịch bản này:

  • Chủ đề A tuyên bố khóa
  • Chủ đề B đợi khóa
  • Chủ đề C đợi khóa
  • Chủ đề A phiên bản khóa . Khóa được gán tùy ý vào chủ đề C
  • Chủ đề D chờ khóa. Bây giờ bạn có chủ đề BD cả hai đang chờ.
  • Chủ đề C giải phóng khóa. Ngay cả thông qua chủ đề B đã chờ lâu nhất, khóa được tùy ý đưa vào luồng D.

Và vì vậy nó tiếp tục cho đến khi cuộc gọi WCF hết giờ và bạn gặp phải lỗi không thể sinh sản.

Nếu tôi phải thực hiện điều này, tôi sẽ có một chuỗi công nhân duy nhất chuyên dụng để tạo tệp PDF. Chủ đề này sẽ được khởi chạy khi dịch vụ đầu tiên khởi động, và nó chờ đợi để lấy một công việc ra khỏi hàng đợi công việc. Mỗi truy vấn WCF sẽ đặt một yêu cầu trên hàng đợi này, và sẽ có một số cách nó có thể chặn cho đến khi nó biết công việc đã được xử lý.

.NET 4.0 cung cấp lớp học BlockingCollection để trợ giúp việc này. (Xem this question)

Điều này mang lại cho bạn cách tiếp cận mà không có giải pháp hoàn chỉnh vì đây không phải là vấn đề tầm thường. Chúc may mắn!

+0

Cảm ơn câu trả lời của bạn, đó là loại thông tin mà tôi đang tìm kiếm. Quá trình trong trường hợp của chúng tôi là khá không thường xuyên nhưng loại đói có thể vẫn có thể xảy ra. Tôi sẽ đưa nó vào tài khoản. – Szymon

0

PDF cần thiết là một thành phần an toàn chủ đề , do đó, có thể tạo tài liệu PDF ở trạng thái đa luồng. Bạn có thể vui lòng tạo ra một sự cố trực tiếp-trac để có được giải pháp.

+0

Vâng, chúng tôi vẫn đấu tranh để có được một phiên bản làm việc đúng từ Syncfusion vì vậy đó không phải là thực sự đúng sự thật. – Szymon

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