2011-12-05 2 views
10

シングルトンパターンに問題があります。C#シングルトンオブジェクトの多くのインスタンス

本当に奇妙ですが、私のシングルトンパターンは2つまたは3つのインスタンスのようです。 私のウェブサイトは、タイマー付きのアクションサイトです。私は自分のシングルトンオブジェクトでタイマーと価格を処理しています。

何が起こっているのは、一部の人々がいくつかの価格を見て、他の人々が異なるネットワークにいるときに常に他の価格を見ているということです。

例えば、私のオフィスでは、オークションは0.56セント、誰もが同じですが、別のネットワーク、たとえば私の家では0.55セント、タイマーは異なる値を示しています。

これは、私がGUIDを生成してログファイルに記録することで、私のシングルトンをテストしたことです。ここではいくつかのコードは、このコードで

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"); 
    } 
} 

で、私は、コンストラクタにトークンを生成し、新しいシングルトンの作成をログに記録し、... SomeAction方法で、私はそのアクションをやっている人ログインします。

この後、私たちはいくつかのテストを行い、ログファイルをダウンロードしました。

私の驚いたことに、「New Singleton Instance bla」というのは正解です。しかし、異なるGUIDを持つメソッドSomeActionへの多くの呼び出しは奇妙です。

オブジェクトが静的コンストラクタでのみ作成されていることを確認しました。手動での作成がないことも確認しました。

詳細については、これは私のプロダクションサーバー(goDaddyホスティング)でのみ発生します。私は私のウェブサイトのための複数のアプリケーションプールがあるかどうか尋ねました、そして、彼らはただ1つのアプリケーションプールがあると言います。

+6

[ここ](http://csharpindepth.com/Articles/General/Singleton.aspx)のようにシングルトンを実装してみてください。 –

+0

私は静的コンストラクタを作成した理由を考えていましたか? – FosterZ

+0

おそらく、Disposeロギングを使用して問題を診断し、あらゆる場所でTryキャッチを追加することができます。がんばろう。 – CodingBarfield

答えて

4

シングルトンの有効期間は、IISの現在のワーカープロセスに関連付けられています。

複数のワーカープロセスが設定されている場合、すべての要求が同じプロセスで処理されるわけではないため、同じシングルトンではありません。

+0

これは理にかなっていますが、私はいくつのワーカープロセスを持っているかを確認します...複数のインスタンスがある場合、どのように同じシングルトンインスタンスを共有できますか?出来ますか? – varholl

+0

これは確かに私の問題です.2つ以上のシングルトンオブジェクトを持つ複数のワーカープロセスがあるので...悲しいことは、メッセージキューまたはリモート処理を使用できないため、どのシンクメソッドも使用できないことです。私は5秒ごとに同期することができるかどうかを確認しようとしていますが、場合によっては...それは待つのに時間がかかります:( – varholl

0

静的コンストラクタは、インスタンスがすでに作成されているかどうかを確認していないようです。ような何か:

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

は、クラス内の他の方法は、実際にinstanceの同じ「インスタンス」を使用していることを確認する必要があります。

私はこれがあなたの問題ですが、それはチェックの価値があるかもしれないことを確かに言うことはできません
+4

-1:これは[静的なコンストラクタ](http://msdn.microsoft.com/en-us/library/k9x6w0hc%28v=VS.100%29)です。 .aspx)。それは一度だけ実行されます... –

+0

再び:静的コンストラクタは一度だけ実行されます。 –

+0

静的コンストラクタ(http://msdn.microsoft.com/en-us/library/k9x6w0hc%28v=VS.100%29.aspx)は一度だけ実行されます。シングルトンの実装に関するJon Skeetの記事(http://www.csharpindepth.com/Articles/General/Singleton.aspx)を見てください。 –

2

  • あなたのロギングフレームワークが初期化される前に、インスタンスを作成する場合は、メッセージがキャッシュされ、または単に取得ん捨てる?ログメッセージは、ログが初期化される前に発生するため、過去に失われているのが見えました。
  • このクラスを含むアセンブリの複数のバージョンを参照している可能性はありますか?これにより、アセンブリバージョンごとのクラスのインスタンスが1つ作成される可能性があるため、表示される値は呼び出すコードによって異なります。しかし、これは、異なる地理的な場所から同じページにアクセスするときに異なる値を見る動作を説明するものではありません。
  • 可能であれば、unique machine idの形式でログを記録して、このコードを1台のマシンで実行することを確認することもできます。 「誰も信じない、すべてを証明する」は、あいまいな行動を理解しようとすると非常に有用な経験則です。
+0

あなたの返信ありがとう!私はログの初期化をチェックします。そのためにメッセージを失うのは意味があります。 binディレクトリに同じdllの複数のバージョンを含めることはできますか?私は私のbinフォルダにGACではないすべてのDLLを持っているということです。 – varholl

+0

同じディレクトリから複数のバージョンの同じアセンブリをロードすることは可能ですが、ファイルの名前を変更するにはちょっとした手間がかかります。 –

1

ウェブサイトでは1つのアプリケーションプールしか使用できませんが、アプリケーションプールによって複数のホストプロセスが生成されることがあります。アプリケーションプールのワーカープロセス数を確認します。

1

あなたが実装したシングルトンパターンがスレッドセーフではないことが問題である可能性があります。 ウェブアプリケーションでは、複数のスレッドが同時に実行されている(ワーカープロセス)ため、2つのスレッドがクラスの2つの異なるインスタンスを作成することがあります。 また、Webアプリケーションの実行場所も考慮する必要があります。 WebファームにWebアプリケーションをデプロイした場合、別のWebサーバーが、Webサーバーのメモリ内の静的変数「live」としてクラスの別のインスタンスを取得する可能性があります。

+0

私のログファイルであなたの返事をありがとう、私は同じトークンを共有する別のスレッドのIDを参照してください、それはスレッドの問題だとは思わない..また、私はロックとmutexほとんどすべての場所を使用してスレッドセーフであることを確認!とにかく私はさらにそれがスレッドセーフであることを確認するために – varholl

+0

WebアプリケーションがWebファームにデプロイされているかどうかをチェックします。この場合、各Webサーバーのインスタンスがあります –

関連する問題