5

独自の接続プールを実装するために使用できる、.net のデータ プロバイダーで使用されるものと同様の標準接続プール モデル(または API) はありますか?

Web サービスで使用する独自の TCP/IP デバイスに独自の接続プールを実装する必要があるためです。現在の問題は、IIS で実行されている Web サービスのスレッド化された性質により、デバイスへの接続が大量にある (読み取りが多すぎる) ことです。独自の接続プールを使用してこれらの接続の数を制限したいのですが、これを行うために使用できる標準モデルがあれば、車輪を再発明するのはばかげているようです。

4

3 に答える 3

6

標準の接続プーリング モデルはありますか

ADO.NET 以外はありません。しかし、ADO.NET モデルは素晴らしくシンプルです。プールから接続を取得するオブジェクトを構築するか、新しく作成すると、クローズ/破棄/ファイナライズ時にプールに返されます。

これからすぐに実装パターンを決定できます。

  • クライアント型は実際の型へのプロキシであり、作成からクローズ/… までの有効期間があります。これは、実際のオブジェクトへのプロキシです。実際の接続に転送するメソッドとプロパティを提供します。
  • 実際の接続は、プールによって作成された存続期間の長いインスタンスであり、プロキシの下で提供され、プロキシの最後に返されます。

実装には選択肢があります。オブジェクトが配布された場合、プールは参照も保持する必要がありますか? その場合、プールはどのオブジェクトがアクティブで、どのオブジェクトがプールされているかを追跡する必要があります。それ以外の場合は、使用可能なオブジェクトの単純なコレクションを使用できます。

何かのようなもの:

internal class MyObjectImpl {
  // The real object that holds the resource
}

internal static class MyObjectPool {
  private static object syncRoot = new object();
  private static Queue<MyObjectImpl> pool = new Queue<MyObject>();
  private static int totalObjects = 0;
  private readonly int maxObjects = 10;

  internal MyObjectImplGet() {
    lock (syncRoot) {
      if (pool.Count > 0) {
        return pool.Dequeue();
      }
      if (totalObjects >= maxObjects) {
        throw new PoolException("No objects available");
      }
      var o = new MyObjectImpl();
      totalObjects++;
      return o;
    }
  }

  internal void Return(MyObjectImpl obj) {
    lock (syncRoot) {
      pool.Enqueue(obj);
    }
  }
}

public class MyObject : IDisposable {
  private MyObjectImpl impl;

  public MyObject() {
    impl = MyObjectPool.Get();
  }

  public void Close() {
    Dispose();
  }

  public void Dispose() {
    MyIObjectPool.Return(impl);
    // Prevent continuing use, as the implementation object instance
    // could now be given out.
    impl = null;
  }

  // Forward API to implement

}

MyObjectこれは、破壊された場合には対応していません。たとえば、割り当てられた への弱い参照のコレクションを保持しMyObject、プールが空の場合は破棄されたインスタンスをチェックします。これは、クライアントがインスタンスを閉じたり破棄したり、MyObjectImpl1にファイナライザーを実装したりすることに依存できない場合にも必要です(そして、これをデバッグ ビルドのエラーとして報告します)。

1 MyObject がファイナライズされるまでに MyObjectImpl インスタンスがすでにファイナライズされている可能性があるため、これは MyObject では実行できません。

于 2009-07-19T08:32:13.910 に答える
4

アップデート

実際、私はより多くのことを知っています。選択したIoC コンテナーの機能であるCastle Windsorを使用すると思います。組み込みのライフスタイルの 1 つに「プール」があります。これは、このライフスタイルに登録されたオブジェクトをコンテナに要求すると、プールされたオブジェクトの 1 つを提供するか、新しいオブジェクトを作成することを意味します。 .

以前...

「オブジェクトプーリング」を実装したいと思います。有望に見えたいくつかのことを次に示します。

もちろん、プールされたオブジェクトでは、並行性やスレッド同期などに注意する必要があります.


データベース接続の場合:

http://msdn.microsoft.com/en-us/library/8xx3tyca(VS . 71).aspx

可能であれば、独自の実装を避けるようにしてください。

于 2009-07-18T20:29:27.500 に答える
0

Webサービスメソッドはステートレスであることが意図されています(つまり、呼び出しの間にサーバー上にオブジェクトが存在し続けることはありません)。実行したいのは、呼び出し間でサーバー上に独自の接続オブジェクトのコレクションを維持し、(各メソッドで新しい接続オブジェクトを作成する代わりに)このプールから各メソッド呼び出しに既存の接続オブジェクトを割り当てることです。

これを行う簡単な方法は、オブジェクトのコレクションをWebサービスのスコープ内で「プライベート静的」として宣言することですが、次のようなメソッドのスコープ外です。

public class Service1 : System.Web.Services.WebService
{
    private static List<CustomConnection> _connections = 
        new List<CustomConnection>();

    [WebMethod]
    public string HelloWorld()
    {
        return "Hello World";
    }
}

次に、Webサービスの起動イベントからコレクションにデータを入力します(現時点でどのイベントが発生しているかは覚えていません。すぐに戻ってきます)。接続を使用する必要があるメソッドは、新しい接続オブジェクトを作成する代わりに、このリストから接続オブジェクトを取得します(接続を割り当て、「使用中」としてマークするなどのメソッドを処理する必要があります)。

これは、Webサービスが頻繁に呼び出される場合に正常に機能します(通常、Webサービスは非アクティブ状態が20分間続くとシャットダウンするため、次の呼び出しのために接続プールを再構築する必要があります)。それを超えて接続のコレクションを維持する必要がある場合は、次の記事を確認してください。

http://msdn.microsoft.com/en-us/library/system.web.httpapplicationstate.aspx

于 2009-07-18T21:55:15.343 に答える