ASP.NET サイトのアプリケーション開始時にバックグラウンド スレッドとして実行されるスケジューラがあります。ユーザーは、データベース テーブルに挿入されるさまざまなタスク (アラート メール/ファイル生成など) を開始できます。スケジューラはデータベースからタスクを選択し、アイテムをスタックにプッシュします。また、スケジューラには 10 個のバックグラウンド スレッドを実行するスレッドプールがあり、スタックからタスク アイテムをポップして実行します。
これは 1 つの Web サーバーでは正常に動作していますが、他の Web サーバーでは奇妙な動作をしています。スレッドは理由もなく 6 ~ 12 秒間アイドル状態になり、スタックに項目があっても何もしません。
- スタック オブジェクトで lock() を使用して Push & Pop スレッド セーフにする
- Thread.Yield() を試して、他のスレッドを実行するために cpu に譲歩を与えましたが、実行が遅くなり、アイドル状態になることはまだ続きます
- Thread.Sleep(0) を試して、他のスレッドを実行するために cpu に譲歩を与えましたが、実行の速度が低下し、アイドル状態になることが引き続き発生します
- 実行中に何か問題が発生していないかどうかを確認するために、すべてのメソッドのエントリと終了をログに記録しましたが、うまくいきませんでした
私の質問:
- .net でのスレッドの実行は決定論的ですか?
- cpu に呼吸時間を与えるために Thread.Yield() または Thread.Sleep(0) を指定する必要がありますか?
- 同じ構成のボックスで動作が異なるのはなぜですか? スレッドの実行に影響を与えるマシン/環境固有の要因はありますか?
2013 年 5 月 8 日の更新
ファームには 2 つのボックスがあり、どちらもハードウェア構成が同じで、同じソフトウェア構成と Windows 2008 64 ビット / IIS7 でセットアップされています。両方の Web サーバーには、同じビルドのサイトが 1 つしかありません。両方のサイトのアプリケーション プールは、統合モードの Framework V4.0 で実行されます。これはレガシー コードであり、過去 2 年間はチャンスがありませんでした。
何度か繰り返してみましたが、いずれの場合も webserver1 は問題なく実行され、以前と同様にバックグラウンド作業が迅速に完了しました。しかし、 webserver2 には大幅な遅延があり、パフォーマンスが非常に悪いです。
すべてのメソッドのエントリ/終了をキャプチャして、広範なログ記録を試みました。シナリオは次のようなものです。すべてのスレッドが 2 秒間正常に動作し、その後 6 ~ 12 秒間アイドル状態になり、再びライブになり、次の 2 秒間実行されてから再びアイドル状態になります。この行動は、タスクが完了するまで一貫しています。例外、アプリケーションの終了、アプリケーション プール/iis ログのエラーはありません。
何か案が ?