1

大量のユーザーをADに大量にインポートするコードを作成しました。サーバーのオーバーロードを避けるために、コードにthread.sleep()を入れて、反復ごとに実行します。

これはメソッドの適切な使用法ですか、それともより良い代替手段がありますか(.NET 4.0がここに適用されます)?

Thread.Sleep()はパフォーマンスにも役立ちますか?スレッドをスリープ状態にすると、コストとパフォーマンスにどのような影響がありますか?

4

7 に答える 7

2

このThread.Sleep()メソッドは、指定された時間だけスレッドを一時停止状態にします。Sleep()3つの異なるタイプからメソッドを呼び出して同じことを実現するには、3つの異なる方法があると言えます。それらはすべて異なる機能を持っています。とにかく最も重要なSleep()のは、メインUIスレッドで使用する場合、その一時停止中にメッセージの処理を停止し、GUIがロックされているように見えることです。スリープする必要のあるジョブを実行するには、BackgroundWorkerを使用する必要があります。

私の意見は、Thread.Sleep()メソッドを使用し、以前のアドバイスに従うことです。あなたの特定のケースでは、問題はないと思います。SOについてまったく同じトピックを探すために努力すれば、前に要約した内容について、はるかに優れた説明が見つかると確信しています。

通常のイベント駆動型システムで発生するように、呼び出されたサービスからフィードバックを受け取る方法がない場合(抽象的に話します。コールバックや、サービスが呼び出しによってどのように影響を受けるかを理解するための情報を言うこともできます)、睡眠は行く方法かもしれません。

于 2012-07-30T23:46:16.740 に答える
1

サーバーに過負荷がかからない場合は、スレッドの優先度を下げることができます。

Thread.Sleep()リソースを消費しないでください。ただし、これを行う正しい方法は、スレッドの優先度を通常よりも低い値に設定することですThread.Current.Priority = ThreadPriority.Lowest。たとえば、

Thread.Sleepそれは「悪、決してやらない」ということではありませんが、おそらく(おそらく)それを使用する必要があるという事実は、ソリューション設計の欠如を反映しています。しかし、これはまったくルールではありません。

個人的には、Thread.Sleepを使用しなければならない状況を見つけることはありません。現在、バックグラウンドスレッドを使用してデータベースからメモリキャッシュに大量のデータをロードし、その後データベースにデータを書き込むASP.NETMVCアプリケーションに取り組んでいます。このスレッドがすべてのWebサーバーとDBプロセッサを消費するのを防ぐために使用した唯一の機能は、スレッドの優先度を最低レベルに下げることでした。通常の優先度のスレッドを使用する場合、そのスレッドは7分ではなく、すべての操作を完了するのに約35分かかります。プロセスの終わりまでに、スレッドはデータベースサーバーに対して約230kの選択を実行しますが、これはユーザーにとって知覚的な方法でデータベースまたはWebサーバーのパフォーマンスに影響を与えません。

ヒント: ThreadPoolのスレッドを使用している場合は、優先度をNormalに戻すことを忘れないでください。

ここでThread.Priorityについて読むことができます:http: //msdn.microsoft.com/en-us/library/system.threading.thread.priority.aspx

実稼働環境でThread.Sleepを使用しない理由についての良い記事があります:http: //msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly -designed-program.aspx

編集他の人がここで言ったように、スレッドの優先度を下げるだけでは、スレッドが多数のコマンド/データをADに送信するのを防ぐことはできません。すべてを考え直してタイマーなどを使うと、より良い結果が得られるかもしれません。個人的には、優先度を下げることで問題を解決できると思いますが、データを使用していくつかのテストを実行し、プロセスに関与するサーバーや他のサーバーに何が起こるかを確認する必要があると思います。

于 2012-07-30T23:51:12.107 に答える
1

Thread.Sleepはこれを処理する1つの方法だと思います。@cHaoは、タイマーを使用すると別の方法でこれを実行できるようになるというのは正しいことです。基本的に、一定期間にADサーバーに送信されるコマンドの数を削減しようとしています。

タイマーを使用する場合は、問題を検出する方法を考案する必要があります(これは、試行/キャッチよりも直感的です)。たとえば、サーバーがストールして応答が遅くなり始めた場合、サーバーが処理できないコマンドをスタックし続けることになります(他のエラーでカスケードする可能性があります)。

ADを使用しているときに、コマンドが多すぎると(DOS攻撃と同様に)ドメインコントローラーが異常終了し、サーバーがクロールまたはクラッシュするのを目にしました。スリープ方式を使用することで、管理可能で測定可能なフローを作成していると思います。

この場合、優先度の低いスレッドを使用すると、速度が低下する可能性がありますが、制御可能なレベルにはなりませんスレッドの優先順位は、コマンドを処理する必要のあるサーバーではなく、コマンドを送信するマシンの要因になります。

お役に立てれば; 乾杯!

于 2012-07-31T00:05:12.533 に答える
0

BelowNormal 代わりに、スレッドを優先的にスケジュールすることができます。そうは言っても、他の何かがサーバーに過負荷をかけた場合、タスクが実行されなくなる可能性があります。(Windowsのスケジューリングが、「一部のオペレーティングシステム」についてスレッドのスケジューリングに関するドキュメントで言及されているように機能すると仮定します。)

そうは言っても、データをADに移動するとおっしゃいました。それがネットワークを超えている場合、AD側でのI / Oおよび処理と比較して、コードのCPUへの影響が無視できる可能性があります。

于 2012-07-30T23:53:18.280 に答える
0

スレッドをスリープ状態にしている間、そのスレッドが応答しないことを除いて、問題はありません。それがメインスレッドの場合、GUIは応答しなくなります。それがバックグラウンドスレッドである場合、あなたはそれと通信することができません(例えばそれをキャンセルするために)。あなたが寝る時間が短いなら、それは問題ではないはずです。

スレッドの優先度を下げることは、1)コードがサーバー上で実行されていない可能性があり、2)サーバーによって実行されている作業のほとんどが、おそらくスレッド上で実行されない可能性があるため、役立つとは思いません。

于 2012-07-30T23:54:50.523 に答える
0

Thread.sleepは、パフォーマンスを向上させません(スレッドが何らかのリソースを待機する必要がある場合を除く)。少なくともある程度のオーバーヘッドが発生し、睡眠時間は保証されません。OSは、指定した時間より長くスレッドをスリープさせることを決定できます。

そのため、Thread.Sleep()の呼び出しの間にかなりのバッチの作業を行う方が理にかなっています。

于 2012-07-30T23:55:36.840 に答える
0

Thread.Sleep()は、CPUを使用しない待機状態です。そのオーバーヘッドはかなり最小限に抑えられるはずです。実行する場合Thread.Sleep(0)、[必然的に]スリープすることはありませんが、スケジューラーが優先度の低いスレッドを実行できるように、タイムスライスを自発的に放棄します。

を設定して、スレッドの優先度を下げることもできますThread.Priority

タスクを制限する別の方法は、Timer:を使用することです。

// instantiate a timer that 'ticks' 10 times per second (your ideal rate might be different)
Timer timer = new Timer( ImportUserIntoActiveDirectory , null , 0 , 100 ) ;

ここImportUserIntoActiveDirectoryで、ユーザーだけをADにインポートするイベントハンドラーはあります。

private void ImportUserIntoActiveDirectory( object state )
{
  // import just one user into AD
  return
}

これにより、ダイヤルインできます。イベントハンドラーはスレッドプールワーカースレッドで呼び出されるため、プライマリスレッドを拘束する必要はありません。OSに任せてください。あなたがすることは、目標のトランザクションレートを決定することだけです。

于 2012-07-31T00:06:09.447 に答える