3

.NET 4.0ランタイムでコンパイルして実行すると、次のようなコードがあります。

int MinWorkerThreads, MaxWorkerThreads;
int MinCompletionPortThreads, MaxCompletionPortThreads;
ThreadPool.GetMinThreads(out MinWorkerThreads, out MinCompletionPortThreads);
ThreadPool.GetMaxThreads(out MaxWorkerThreads, out MaxCompletionPortThreads);
_logger.Info("Default thread pool settings min/max:");
_logger.Info("Worker thread: " + MinWorkerThreads + " / " + MaxWorkerThreads);
_logger.Info("IO thread    : " + MinCompletionPortThreads + " / " + MaxCompletionPortThreads);
_logger.Info("Setting minimum default worker thread count to " + Config.MinWorkerThreads);
if (!ThreadPool.SetMinThreads(Config.MinWorkerThreads, MinCompletionPortThreads))
{
    _logger.Warn("Unable to modify the minimum number of worker threads");
}
ThreadPool.GetMinThreads(out MinWorkerThreads, out MinCompletionPortThreads);
_logger.Info("Worker thread: " + MinWorkerThreads + " / " + MaxWorkerThreads);

ロギング出力は次のようになります。

Default thread pool settings min/max:
Worker thread: 4 / 32767
IO thread    : 4 / 1000
Setting minimum default worker thread count to 50
Worker thread: 50 / 32767

値はすぐに変更されますが、永続的には変更されません。

なぜ私はこれをしているのですか? Timer■デフォルトのThreadPoolを使用すると、突然のタスクのバッチがシステムスレッドプールに入り、それを圧倒し、15秒ごとにトリガーされるはずのタイマーが60秒以上遅延することがあります。

問題は、同じコードを使用して同じ情報をランタイムに15分ダンプすると、非常に異なる値が取得されることです。

Worker thread: 4 / 400
IO thread    : 4 / 400

の使用を断念せずにこの問題を解決するためのより良い方法はありSystem.Timers.Timerますか?IISをまったく含まないスタンドアロンのC#アプリケーションでこの値をリセットするにはどうすればよいですか?ASP.NETをセルフホスティングしている場合、システムスレッドプールの調整は暗黙的に変更されますか?

4

1 に答える 1

3

別のアプローチをお勧めします。

ThreadPool からすべてのブロッキング コードを削除します。それは設計されたものではありません。

IO バウンドの操作がある場合は、すべての段階で非同期にします。

CPU バウンドの操作がある場合は、それらを ThreadPool スレッドで実行しないでください。

これらのルールに厳密に従うことで、ThreadPool パラメーターをいじる必要がなくなります。お気づきのように、レスポンシブな ThreadPool に完全に依存している .Net API が多すぎます。スレッドをむさぼり食うだけの場合、どれだけ多くのスレッドを選択しても、プログラムを十分に長く/ハードに実行すると、再び制限に達する可能性が非常に高くなります。

意図したとおりに ThreadPool を使用します... 主に IO の結果を適切な場所にマーシャリングするための短命のロジックです。

于 2013-02-11T23:28:00.110 に答える