4

私はbasicHttpBindingでServiceContractを公開するWCFサービスを持っているので、私の理解では、InstanceContextModeはPerCallに設定され(basicHttpBindingはセッションをサポートしていないため)、ConcurrenyModeはSingleに設定されます。

この WCF のクライアントは Windows サービスであり、サービス上で同時に 4 つの異なる操作を呼び出します。サービス内ではシングルトン クラスを使用しており、静的変数はほとんどありません。一部の DB ストアド プロシージャに間違った値が渡されるという問題に直面しています。

PerCall InstanceContextMode と Single 同時実行モードでは、呼び出しごとに新しいサービス インスタンスが作成されることを理解しています。そのため、サービス実装と静的変数にいくつかのシングルトン クラス (スレッド セーフにはしていません) があるにもかかわらず、オブジェクトは破棄されますが、古い値が DB に渡される SQL プロファイラーを実行していることが確認されています。

WCF サービス コードを一種の 3 層アーキテクチャ、つまり ServiceClass、BusinessLogicLayer、および DataAccessLayer で記述しました。PerCall を instanceContextMode として設定し、クライアント リクエストが終了した後にサービス インスタンスが破棄されると言いましたが、すべてを破棄するということですか? ServiceClass、BusinessLogicLayer、および DataAccessLayer のオブジェクト?

何が問題なのかを理解するのを手伝ってください

4

3 に答える 3

0

あらゆる方法で制限されていますが、ベスト プラクティスとして、スレッド セーフのために静的変数を保護する必要があります。静的変数は、サービスが停止されるかアプリ プールがリサイクルされるまで破棄されません。

変更されるデータに静的変数を使用することは、分散 Web ファームでは推奨されません。これは、フェールオーバーよりも安全ではないためです。

Visual Studio 2012 以降には、メモリ プロファイラーが付属しています。しかし、簡単なことは、オブジェクト コンストラクターのカウンターを使用して (テスト時のみ)、すべての要求で作成された新しいインスタンスがあるかどうかを確認することで実行できます。

   [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall,ConcurrencyMode=ConcurrencyMode.Single)]
public class TestServiceWithStaticVars : ITestServiceWithStaticVars
{
   static int instanceCount = 0;
    public TestServiceWithStaticVars()
    {
        Interlocked.Decrement(ref instanceCount);
    }
    public string GetInstanceCount()
    {
        return string.Format("You have created {0} instance", instanceCount);
    }

簡単に使用できるより良いインスタンスカウンターが利用可能かどうかをお知らせください。

【追記】今はコメントできないので。

あなたが言ったように、静的変数を再割り当てすると、新しい値が取得されます。静的変数は、頻繁にアクセスするために HighFrequencyHeap に読み込まれます。詳細についてはhttp://www.codeproject.com/Articles/15269/Static-Keyword-Demystified

于 2014-11-15T15:23:08.363 に答える
0

InstanceContextMode PerCallは、サービスの新しいクラスが呼び出しごとにインスタンス化されることを意味します。AppDomain の静的変数はリセットされません。AppPool がリサイクルされない限り、それらはサービス コール間で保持されます。

コードからシングルトンを含むすべての静的を削除します。とにかく、それらはあなたのアーキテクチャに属していませんでした。

于 2014-11-15T11:17:43.603 に答える
0

多くの WCF 要求は、同じ AppDomain を共有します。静的変数は AppDomain ごとです。WCF はこれらの変数に対して何もしません (実際、それらが存在することを見つけることさえできません)。あなたはそれらを維持する責任があります。

WCF はオブジェクトの意味を理解しておらず、オブジェクトの存在も認識していないため、WCF はオブジェクトを破棄しません。

あなたが言及した設定は、サービスオブジェクトにのみ関連しています。

ステートフル サーバー アプリに関する私の通常のアドバイス: ここでは悪い慣行の下で作業しています。スレッドセーフを確保する必要があります。ワーカー プロセスがシャットダウンした場合 (デプロイ、自動再起動、サーバーの再起動、アプリのバグによるプロセスのクラッシュ、停電、ハードウェア障害など)、データは失われます。

于 2014-11-15T11:17:56.647 に答える