0

IIS 7 でホストされている WCF Web サービスがあります。この Web サービスは、モバイル アプリで使用する JSON コンテンツを提供します。MS SQL 2005 の上で Entity Framework を使用し、インターフェイス コントラクトは次のようになります。

   [ServiceContract]
    public interface MyService
    {
        [WebInvoke(Method = "GET", UriTemplate = "/GetStuff?skip={skip}&take={take}&loanAmt={loanAmt}&propertyVal={propertyVal}&Term={Term}&MonthlyRent={MonthlyRent}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        [OperationContract]
        ProductsDTO GetProducts(int skip, int take, decimal loanAmt, decimal propertyVal, int Term, decimal MonthlyRent);
    }

実装は次のようになります。

    public ProductsDTO GetProducts(int skip, int take, decimal loanAmt, decimal propertyVal, int Term, decimal MonthlyRent)
    {
       //Some set up code
      using (MyEntities context = new MyEntities()) 
        {
              //Get our products
        }

     return ReturnedList
    }

これを最初に実行すると、最大 15 秒かかります (モバイル アプリでは許容できません)。その後の実行では、データは 1 秒以内に返されます。非アクティブ状態が 5 分間続くと、WCF サービスは開始に 15 秒かかる状態に戻ります。

私は最初、ボトルネックが IIS7 にあると考え、アプリケーション プールが停止していると考えました。アプリケーション プールをリサイクルしないように設定し、IIS サーバーで w3wp.exe プロセスを調べたところ、そうではないことがわかりました。その 5 分後にシャットオフされるのは、データベース セッションです。

この場合、WCF アプリケーションからの要求をすぐに処理するために SQL セッションを開いたままにしたいのですが、エンティティ コンテキストをシングルトンとして設定したり、これをサービスで開いたままにしたりしたくありません。悪い練習。(MyEntities context = new MyEntities(MySQLConnection)) を使用して SQL 接続オブジェクトをコンテキストに渡し、それを開いたままにすることができますか? または、誰かが何か他のことを提案できますか?

Web サービスを維持するために Web サービスにアクセスするスクリプトを含む多くの投稿を見たことがあり、忍び寄る恐怖を感じたので、このルートをたどることは避けてきました。

あなたの考えは何ですか?

更新 1

Andomars の回答に従って、次の初期化コードを WCF サービスに追加しました。

   public Service1()
        {
            // Blocking call that initializes
            // the service instance
            this.Initialize();
        }

        BackgroundWorker KeepSQLAlive = new BackgroundWorker();

        private void Initialize()
        {
            KeepSQLAlive.DoWork += new DoWorkEventHandler(KeepSQLAlive_DoWork);

            KeepSQLAlive.RunWorkerAsync();
        }

        void KeepSQLAlive_DoWork(object sender, DoWorkEventArgs e)
        {
            Timer pingback = new Timer(180000);

            pingback.Elapsed += new ElapsedEventHandler(pingback_Elapsed);

            pingback.Start();
        }

        void pingback_Elapsed(object sender, ElapsedEventArgs e)
        {
            using (MyEntities context = new MyEntities ())
            {
                context.ExecuteStoreCommand("select @@servername");
            }
        }

これは少しごちゃごちゃしているように感じます。シングルトンとしてサービスを作成しないと、サービスが SQL セッションを強制終了することなく生成し続けるのではないかと少し心配です。ただし、それが機能する場合、Windows サービスでこのコードをホストすると時間がかかり、これを IIS セキュリティ (SSL を使用したい) と統合する方法が不明であるため、抵抗が最も少ないパスです。上記が動作するかどうかはまた報告します。(すべての支援に感謝します)

4

2 に答える 2

1

毎分実行されるバックグラウンド スレッドselect @@servername(または別の簡単なクエリ) を追加できます。これにより、接続プールが暖かく保たれます。

于 2012-05-22T11:17:44.570 に答える
0
  1. Web サービスはバックグラウンド スレッドを実行すべきではないため、..
  2. IIS とデータベース間のプロキシとして WCF コントラクトを使用して Windows サービスを作成します。
  3. Windows サービスで接続プールを使用していることを確認してください。
  4. Windows サービスから 30 秒 / 1 分 / 5 分 (今回はテストする必要があります) ごとに DB からクエリを実行します。クエリの後、接続を閉じることを忘れないでください (これにより実際の接続は閉じられませんが、プールで接続が使用可能になります)。これにより、プール内のアクティブな接続が少なくとも 1 つ維持され、リクエストに対応できるようになります。
  5. IIS 上の WCF サービスと Windows サービスの間でパイプ (NetNamedPipeBinding) を使用します (高速です)。
  6. IIS で既にコンパイル済みのアプリケーションを公開することを考えてみてください。リンク
于 2012-05-22T11:33:30.453 に答える