使用すべきではないとよく言われますThread.Sleep();
が、なぜそうなのか理解できません。Thread.Sleep();
問題を引き起こす可能性がある場合、同じ結果になり、安全である代替の解決策はありますか?
例えば。
while(true)
{
doSomework();
i++;
Thread.Sleep(5000);
}
もう一つは:
while (true)
{
string[] images = Directory.GetFiles(@"C:\Dir", "*.png");
foreach (string image in images)
{
this.Invoke(() => this.Enabled = true);
pictureBox1.Image = new Bitmap(image);
Thread.Sleep(1000);
}
}
ベストアンサー1
電話をかける際の問題Thread.Sleep
はここで簡潔に説明されている:
Thread.Sleep
用途はあります: MTA スレッドでテスト/デバッグしながら長時間の操作をシミュレートします。.NET では、これを使用する理由は他にありません。
Thread.Sleep(n)
は、現在のスレッドを、少なくともn
ミリ秒以内に発生するタイムスライス数 (またはスレッド クォンタム数) の間ブロックすることを意味します。タイムスライスの長さは、Windows のバージョン/タイプやプロセッサによって異なりますが、通常は 15 ~ 30 ミリ秒の範囲です。つまり、スレッドがn
ミリ秒以上ブロックされることはほぼ確実です。スレッドがちょうどミリ秒後に再び起動する可能性は、n
ほぼあり得ません。だからThread.Sleep
タイミングは無意味だ。スレッドは限られたリソースであり、作成には約 200,000 サイクル、破棄には約 100,000 サイクルかかります。デフォルトでは、スタック用に 1 MB の仮想メモリが予約され、コンテキスト スイッチごとに 2,000 ~ 8,000 サイクルが使用されます。これにより、待機中のスレッドは巨大な無駄。
推奨される解決策:待機ハンドル
最もよくある間違いは、Thread.Sleep
while構文(デモと回答、素敵なブログ記事)
編集:
私の回答を補足したいと思います。
2 つの異なるユースケースがあります。
継続すべき特定の期間がわかっているため、待機しています(
Thread.Sleep
、System.Threading.Timer
または同様のものを使用)状況が変わる可能性があるので待機しています...キーワードはいつか! 条件チェックがコードドメイン内にある場合は、WaitHandles を使用する必要があります。そうでない場合は、外部コンポーネントが何らかのフックを提供する必要があります。そうでない場合は、設計が間違っています。
私の回答は主にユースケース2をカバーしています