2012-12-25 33 views
7

Không thể hiểu tại sao hàm tạo kiểu cho PerSession/dịch vụ WCF đã gọi hai lần. ConcurrencyModeMultiple. Chỉ cần khởi chạy năm ứng dụng khách đồng thời thực hiện cùng một phương thức dịch vụ WCF, trong nhật ký tôi thấy rằng hàm tạo static được gọi hai lần, lần đầu tiên và sau 3 giây lần thứ hai với ProcessId/ThreadId khác. Không có ngoại lệ nào trong bản thân nhà xây dựng cũng như bản ghi nhật ký WCF. Thời gian thực thi Constructor là ~ 10 mili giây theo log. Kết quả này trong tất cả các trường tĩnh không được chia sẻ giữa tất cả các cá thể dịch vụ như trong trường hợp và trong trường hợp có 5 kết nối máy khách, tôi có 5 dịch vụ và hai ngữ cảnh tĩnh khác nhau để thay đổi trong trường tĩnh đang diễn ra không được phản ánh cho tất cả các dịch vụ.Hàm tạo tĩnh được gọi hai lần cho dịch vụ WCF của PerSession

Vấn đề này gây nhầm lẫn nhiều thứ vì tôi dựa vào một số bộ đệm tĩnh được chia sẻ trên nhiều phiên bản dịch vụ.

Dịch vụ được lưu trữ trong IIS. Không có IIS khởi động lại, AppPool sẽ tái chế vào khoảng thời gian này.

[AspNetCompatibilityRequirements(RequirementsMode = 
    AspNetCompatibilityRequirementsMode.Allowed)] 
[ServiceBehavior(
    InstanceContextMode = InstanceContextMode.PerSession, 
    IncludeExceptionDetailInFaults = true, 
    ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class WcfService 
{ 
    private static readonly ILog logger; 
    private static volatile bool typeInitialized; 

    static WcfService() 
    { 
     try 
     { 
      // Here is typeInitialized is false in both calls 
      logger = LogManager.GetLogger("LogName"); 

      logger.InfoFormat("[PID:{0}] [THID:{1}] BEGIN Static constructor", 
       Process.GetCurrentProcess().Id, 
       Thread.CurrentThread.ManagedThreadId); 
     } 
     catch (Exception exception) 
     { 
      logger.Error("error on type construction stage", exception); 
     } 
     finally 
     { 
      logger.InfoFormat("[PID:{0}] [THID:{1}] END Static constructor", 
       Process.GetCurrentProcess().Id, 
       Thread.CurrentThread.ManagedThreadId);    
      typeInitialized = true; 
     } 
    } 
} 
+0

Nếu mục tiêu của bạn là đảm bảo chỉ một phiên bản được tạo, bạn có thể muốn triển khai mẫu Singleton cho lớp này: http://en.wikipedia.org/wiki/Singleton_pattern – Nogard

+2

@Nogard và điều đó sẽ hoàn toàn vô dụng trong trường hợp này trường hợp như IIS đang mở nhiều trường hợp của chương trình, mà tất cả đều vui khi có singleton riêng của họ. Các hàm tạo tĩnh cũng được định nghĩa là được gọi là CHỈ ONCE ON LOAD CLASS - nhưng điều đó không ngăn người dùng có các appdomain riêng biệt tải các lớp riêng biệt, như trường hợp với IIS. – TomTom

Trả lời

6

Giả sử bạn đang lưu trữ dịch vụ của mình với IIS, đây là hành vi bình thường trừ khi bạn định cấu hình rõ ràng quá trình chỉ cho phép một AppDomain được tách ra.

Nếu bạn xem danh sách các quy trình đang chạy, bạn sẽ thấy mỗi Id quá trình trong nhật ký của bạn tương ứng với một bản sao của w3wp.exe lưu trữ tên miền ứng dụng riêng biệt.

+0

Bạn nói đúng, đây là dịch vụ được lưu trữ trên IIS. Quên đề cập đến điều này. Chỉ cần cập nhật câu hỏi. Tôi có thể thiết lập hành vi đơn 'AppDomain' chỉ cho một dịch vụ WCF cụ thể không? Bởi vì xung quanh là các dịch vụ khác vì vậy tôi không muốn mess lên bất cứ điều gì khác – sll

+0

Tôi đã có 2 quy trình công nhân cho mỗi AppPool, sau khi thay đổi để '1' everythign làm việc tốt cho đến nay, anyway đánh giá cao bất kỳ lời khuyên liên quan đến xác định rõ ràng để lưu trữ tất cả các trường hợp WCF trong quá trình tương tự – sll

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