0
// procedural 
foreach (var foo in bar)
{                                 
    foo.someProperty = getData(ref foo);     
}

// threaded
foreach (var foo in bar)
{                                         
    ThreadStart work = delegate
    {
        getData(ref foo);
    };

   new Thread(work).Start();    
}

getData(ref foo){

    // Either  a LINQ query 

    // Or Exec Command to Stored procedure in SQL Server

    // Either taking approx 2 seconds to return results

    foo.someProperty = resultsFromDBOrLinqStatement;
}

bar に 20 個の項目がある場合、単純に手続き型の foreach ループを使用すると、約 10 秒かかります。リクエストを次々に実行し、毎回 DB を呼び出します。

同じデータに対して、スレッド化された for each ループが使用されると、リクエストに時間がかかりますか?! スレッドがすべて問題なくても、各スレッドからの DB への要求が滞っているように見えます。

getData() メソッドを次のように変更すると、

getData(ref foo){

    thread.sleep(4000);
}

次に、予想どおり、リクエスト全体が 4 秒で完了します。すべてのスレッドがほぼ同時に起動し、同時に実行され、4 秒後に終了します。

このプロセス全体を遅くしている各スレッドの DB 呼び出しに関して何か不足していますか? - DB などへの同時接続のための web.config 設定はありますか?

PS。並列 foreach と Tasks を試しましたが、データベース サーバーがすべての呼び出しをキューに入れているかのように、常にデータベース呼び出しでスレッド化に戻り、速度が低下します。

4

2 に答える 2

0

マルチスレッドは、スレッド作成のコスト (時間、リソース) が手続き型実行時間の合計よりも少ない場合に効果を発揮します。

于 2012-07-19T10:01:34.507 に答える
0

SQL サーバー (またはその他のデータベース サーバー) への並列要求は、次の条件がすべて満たされている場合にのみ高速になります。

  1. サーバーには、着信要求ごとに 1 つのアイドル状態のプロセッサ コアがあります (実際には、要求ごとに 1 つのスレッドを使用します)。
  2. 各着信要求には、異なるファイル (データベース、テーブルなど、実際のサーバーに応じて) が含まれます。
  3. ファイルの各バッチ (リクエストごとに 1 つ) は、独自の HDD にあります。
  4. サーバーには、すべての要求と関連するすべてのデータを同時に処理するのに十分な空き物理メモリがあります
  5. サーバー プロセスがメモリ不足になることはありません (可能性は低いですが、32 ビット システムでは大量のデータを要求する場合...)

(サーバーに SSD が搭載されている場合、ポイント 2 と 3 は問題ではありません。SSD では、複数のファイルを並列および順次に読み取る累積時間はほぼ同じです)

それ以外の場合、プログラムを高速化する方法は 1 つしかありません (サーバーを高速化する以外に、これは常に可能というわけではありません)。 、大きな結合を減らす...)。

于 2012-07-19T10:48:48.720 に答える