0

私は.NET 4.0コンソールアプリを書いています

  1. 接続を開きます データ リーダーを使用して、キーのリストをカーソルで表示します

  2. キーが読み取られるたびに、Web サービスを呼び出します

  3. Web サービスの結果をデータベースに格納します

次に、1 秒あたりに処理できるレコードの最大数を改善するために、このプロセスの複数のスレッドを生成します。

約 30 スレッドを超えてプロセスを起動すると、次のエラーが発生します。

System.InvalidOperationException: Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.   This may have occurred because all pooled connections were in use and max pool size was reached.

接続プールからより多くの接続を取得できるように調整するサーバーまたはクライアント側のオプションはありますか?

SQL 2008 r2 DATABASE を呼び出しています。

どうも

4

3 に答える 3

1

これは設計上の問題のように聞こえます。データベースからの総レコード数は? リーダーを反復処理すると、非常に高速になります。何十万行もある場合でも、そのリーダーを通過するのは迅速です。これはあなたが取ることができる別のアプローチです:

リーダーを反復処理し、データをオブジェクトのリストに格納します。次に、選択した数 (一度に 2 つ、一度に 3 つなど) でオブジェクトのリストを繰り返し処理し、その数のスレッドを生成して Web サービスを並行して呼び出します。

この方法では、データベースへの複数の接続を開くことはなく、真のボトルネックとなる可能性のあるもの (Web サービスへの HTTP 呼び出し) に並行して対処できます。

次に例を示します。

List<SomeObject> yourObjects = new List<SomeObject>();

if (yourReader.HasRows) {
    while (yourReader.Read()) {
        SomeObject foo = new SomeObject();
        foo.SomeProperty = myReader.GetInt32(0);
        yourObjects.Add(foo);
    }
}

for (int i = 0; i < yourObjects.Count; i = i + 2) {
    //Kick off your web service calls in parallel.  You will likely want to do something with the result.
    Task[] tasks = new Task[2] {
        Task.Factory.StartNew(() => yourService.MethodName(yourObjects[i].SomeProperty)),
        Task.Factory.StartNew(() => yourService.MethodName(yourObjects[i+1].SomeProperty)),
    };

    Task.WaitAll(tasks);
}

//Now do your database INSERT.
于 2012-04-27T17:40:35.043 に答える
0

すべてのリクエストに対して新しい接続を開くことは、非常に非効率的です。単に同じ接続を使用して要求を続けたい場合は、それは可能以上のことです。接続を開いて、その1つの接続を介してできるだけ多くのSqlCommandコマンドを実行できます。ONE接続を維持し、すべてのスレッド化が完了したら破棄します。

于 2012-04-27T17:40:59.817 に答える