2011-12-05 37 views
10

Tôi gặp sự cố với mẫu Singleton.C# Nhiều trường hợp của một đối tượng Singleton

Thật kỳ lạ, nhưng có vẻ như có hai hoặc ba trường hợp Mẫu Singleton của tôi. Trang web của tôi, là trang web hành động, có tính giờ và tôi đang xử lý các bộ tính giờ và giá đó với đối tượng Singleton của tôi.

Điều đang xảy ra là một số người thấy một số giá và những người khác nhìn thấy giá khác luôn khi họ ở trong các mạng khác nhau. Ví dụ, Trong văn phòng của tôi, người của tôi thấy một số cuộc đấu giá ở mức 0,56 cent, mọi người đều thấy như nhau, nhưng trong một mạng khác, ví dụ, nhà của tôi, tôi thấy 0,55 cent và đồng hồ cũng có giá trị khác nhau.

Có nói điều này, tôi đã thử nghiệm Singleton của tôi, bằng cách tạo ra một GUID và đăng nhập nó trong tệp nhật ký của tôi. Dưới đây là một số mã

public class Singleton 
{ 
    private static Singleton instance; 
    private static System.Threading.Mutex mutex; 

    System.Guid token; 

    private Singleton() { 
     token = System.Guid.NewGuid(); 
     Logger.Log("New singleton Instance" + token.toString()); 
    } 
    static Singleton() 
    { 
     instance = new Singleton(); 
     mutex = new System.Threading.Mutex(); 
    } 

    public static Singleton Acquire() 
    { 
     mutex.WaitOne(); 
     return instance; 
    } 

    // Each call to Acquire() requires a call to Release() 
    public static void Release() 
    { 
     mutex.ReleaseMutex(); 
    } 

    public void SomeAction() 
    { 
     Logger.Log(token.toString() + " - SomeAction"); 
    } 
} 

Trong mã này, tôi tạo ra các mã thông báo các nhà xây dựng, và đăng nhập tạo ra một Singleton mới, sau đó ... trong phương pháp SomeAction, tôi đăng nhập người đang làm hành động đó.

Sau đó, chúng tôi đã thực hiện một vài thử nghiệm và tải xuống tệp nhật ký.

Trước sự ngạc nhiên của tôi, tôi chỉ thấy một "Singleton Instance bla mới" là chính xác. nhưng sau đó, nhiều cuộc gọi đến phương thức SomeAction với các GUID khác nhau, điều này thật kỳ lạ.

Tôi đã kiểm tra đối tượng đó chỉ được tạo trong hàm dựng tĩnh và tôi cũng đã kiểm tra rằng không có tạo thủ công ở bất kỳ đâu.

Để biết thêm thông tin, điều này chỉ xảy ra trên máy chủ sản xuất của tôi, lưu trữ goDaddy. Tôi đã hỏi nếu có nhiều hơn một hồ bơi ứng dụng cho trang web của tôi và họ nói rằng chỉ có một ứng dụng Pool.

+6

Hãy thử triển khai singleton của bạn như được đề xuất [ở đây] (http://csharpindepth.com/Articles/General/Singleton.aspx). –

+0

tôi đã suy nghĩ tại sao bạn đã tạo ra constructor tĩnh? – FosterZ

+0

Có thể bạn có thể chẩn đoán sự cố bằng cách sử dụng tính năng Ghi nhật ký vứt bỏ và thêm Thử Bắt ở mọi nơi. Chúc may mắn. – CodingBarfield

Trả lời

4

Thời gian sử dụng đơn lẻ của bạn được gắn với quá trình nhân viên hiện tại của IIS.

Nếu bạn có nhiều quy trình công nhân được định cấu hình thì không phải tất cả các yêu cầu đều được xử lý bởi cùng một quá trình và do đó không phải cùng một singleton.

+0

Điều này có ý nghĩa, tôi sẽ kiểm tra xem tôi có bao nhiêu quy trình công nhân ... Trong trường hợp tôi có nhiều hơn một, bạn có biết làm cách nào để chia sẻ cùng một cá thể đơn? Có thể không? – varholl

+0

Đây rõ ràng là vấn đề của tôi, vì có nhiều hơn một quy trình công nhân tôi có nhiều hơn một đối tượng đơn lẻ ... Điều đáng buồn là tôi không thể sử dụng bất kỳ phương thức đồng bộ nào vì tôi không thể sử dụng hàng đợi Tin nhắn hoặc từ xa .. Tôi đang cố gắng để xem nếu tôi có thể đồng bộ hóa mỗi 5 giây nhưng trong một số trường hợp ... đó là quá nhiều thời gian để chờ đợi: ( – varholl

0

Dường như nhà xây dựng tĩnh của bạn không kiểm tra xem liệu cá thể đó đã được tạo chưa. Một cái gì đó như:

static Singleton() 
    { 
    if (instance == null) 
     { 
     instance = new Singleton(); 
     mutex = new System.Threading.Mutex(); 
     } 
    } 

phải đảm bảo rằng các phương pháp khác trong lớp đang thực sự sử dụng cùng một "trường hợp" instance.

+4

-1: Đây là [hàm dựng tĩnh] (http://msdn.microsoft.com/en-us/library/k9x6w0hc%28v=VS.100%29 .aspx). Nó chỉ được thực hiện một lần ... –

+0

Một lần nữa: Các hàm tạo tĩnh chỉ được thực hiện một lần. –

+0

Một hàm tạo tĩnh (http://msdn.microsoft.com/en-us/library/k9x6w0hc%28v=VS.100%29.aspx) chỉ được thực hiện một lần. Xin hãy xem bài viết của Jon Skeet về việc triển khai Singletons (http://www.csharpindepth.com/Articles/General/Singleton.aspx). –

2

Tôi không thể nói chắc chắn rằng đây là vấn đề của bạn, nhưng nó có thể là giá trị kiểm tra:

  • Nếu bạn tạo một thể hiện trước khung đăng nhập của bạn được khởi tạo, không được thông báo được lưu trữ, hoặc chỉ vứt bỏ? Tôi đã nhìn thấy các thông điệp tường trình bị thiếu trong quá khứ vì chúng xảy ra trước khi đăng nhập được khởi tạo.
  • Có thể bạn đang tham chiếu nhiều phiên bản của hội đồng có chứa lớp này không? Điều này có thể gây ra một thể hiện của lớp trên mỗi phiên bản assembly được tạo ra, vì vậy các giá trị được nhìn thấy sẽ phụ thuộc vào mã gọi nó. Tuy nhiên, điều này sẽ không giải thích được hành vi bạn thấy về các giá trị khác nhau khi truy cập vào cùng một trang từ các vị trí địa lý khác nhau.
  • Tôi cũng sẽ bị cám dỗ để đăng nhập một số hình thức unique machine id nếu bạn có thể, để xác minh rằng chỉ có một bản sao của mã này chạy trên một máy. "Tin tưởng không ai, chứng minh tất cả mọi thứ" là một heuristic rất hữu ích khi cố gắng hiểu hành vi tối nghĩa.
+0

Cảm ơn bạn đã trả lời! Tôi sẽ kiểm tra việc khởi tạo nhật ký, nó có thể có ý nghĩa để mất những thông điệp đó vì điều đó. Có thể có nhiều phiên bản của cùng một dll trong thư mục bin không? Tôi có nghĩa là tôi có tất cả các dll của tôi trên thư mục bin của tôi không phải là GAC. – varholl

+0

Tôi tin rằng có thể tải nhiều phiên bản của cùng một assembly từ cùng một thư mục, nhưng phải mất một chút thủ thuật xung quanh việc đổi tên các tập tin, vì vậy bạn không thể làm điều đó một cách tình cờ. –

1

Trang web của bạn chỉ có thể sử dụng một nhóm ứng dụng, nhưng một hồ bơi ứng dụng có thể sinh ra nhiều quá trình lưu trữ. Kiểm tra số lượng quy trình công nhân cho hồ bơi ứng dụng của bạn.

1

Vấn đề có thể là mẫu singleton bạn đã triển khai không phải là chủ đề an toàn. vì trong một ứng dụng web, bạn có nhiều hơn một luồng chạy cùng một lúc (quy trình công nhân), có thể xảy ra hai luồng tạo hai thể hiện khác nhau của lớp của bạn. Bạn cũng nên xem xét nơi ứng dụng web của bạn đang chạy. Nếu bạn đã triển khai ứng dụng web của mình trên một trang trại, có thể xảy ra rằng máy chủ web khác nhau có một phiên bản khác của lớp của bạn dưới dạng biến tĩnh "sống" trong bộ nhớ của máy chủ web.

+0

Cảm ơn bạn đã trả lời, trong tệp nhật ký, tôi thấy các Id chủ đề khác nhau dùng chung mã thông báo, Vì vậy, tôi không nghĩ rằng đó là vấn đề về chuỗi .. tôi cũng đảm bảo an toàn bằng cách sử dụng khóa và mutex hầu như ở mọi nơi! anyways tôi sẽ kiểm tra thêm để chắc chắn rằng nó là thread an toàn – varholl

+0

kiểm tra cũng nếu các ứng dụng web được triển khai trên một trang trại. Trong trường hợp này, bạn sẽ có một cá thể cho mỗi máy chủ web –

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