C#プログラムを50ミリ秒間スリープさせるにはどうすればよいですか?
これは簡単な質問のように思えるかもしれませんが、私は一時的な脳の障害の瞬間を抱えています!
C#プログラムを50ミリ秒間スリープさせるにはどうすればよいですか?
これは簡単な質問のように思えるかもしれませんが、私は一時的な脳の障害の瞬間を抱えています!
回答:
System.Threading.Thread.Sleep(50);
ただし、メインGUIスレッドでこれを行うと、GUIの更新がブロックされることを覚えておいてください(「緩慢」に感じる)
;
VB.netでも機能するように削除するだけです。
(ほぼ)すべてのプログラミング言語で待機するには、基本的に3つの選択肢があります。
for 1.-C#での緩やかな待機:
Thread.Sleep(numberOfMilliseconds);
ただし、Windowsスレッドスケジューラの精度はSleep()
約15ミリ秒です(したがって、1ミリ秒だけ待機するようにスケジュールされている場合でも、スリープは簡単に20ミリ秒待機できます)。
for 2-C#でのタイトな待機は次のとおりです。
Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
//some other processing to do possible
if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
{
break;
}
}
DateTime.Now
時間測定のその他の手段を使用することもできますStopwatch
が、はるかに高速です(これは、タイトループで実際に表示されます)。
3.の組み合わせ:
Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
//some other processing to do STILL POSSIBLE
if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
{
break;
}
Thread.Sleep(1); //so processor can rest for a while
}
このコードは定期的にスレッドを1ミリ秒(またはOSスレッドのスケジューリングによってはそれ以上)ブロックします。そのため、そのブロックの間プロセッサはビジーではなく、コードはプロセッサの電力を100%消費しません。その他の処理は、ブロックの間に実行することもできます(UIの更新、イベントの処理、対話/通信など)。
Windowsでは正確なスリープ時間を指定することはできません。そのためにはリアルタイムOSが必要です。最善の方法は、最小スリープ時間を指定することです。その後、スケジューラーがスレッドをウェイクアップするかどうかが決まります。また、GUIスレッドを呼び出さないでください.Sleep()
。
これで非同期/待機機能が利用できるようになったので、50ms間スリープする最善の方法はTask.Delayを使用することです。
async void foo()
{
// something
await Task.Delay(50);
}
または、.NET 4(VS2010の非同期CTP 3またはMicrosoft.Bcl.Asyncを使用)をターゲットにしている場合は、以下を使用する必要があります。
async void foo()
{
// something
await TaskEx.Delay(50);
}
このようにして、UIスレッドをブロックしません。
FlushAsync
バージョンがあると思います。
async
宣言を必要としない別の方法は、電話をかけることですTask.Delay(50).Wait();
このコードを使用
using System.Threading;
// ...
Thread.Sleep(50);
両方の長所:
using System.Runtime.InteropServices;
[DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]
private static extern uint TimeBeginPeriod(uint uMilliseconds);
[DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
private static extern uint TimeEndPeriod(uint uMilliseconds);
/**
* Extremely accurate sleep is needed here to maintain performance so system resolution time is increased
*/
private void accurateSleep(int milliseconds)
{
//Increase timer resolution from 20 miliseconds to 1 milisecond
TimeBeginPeriod(1);
Stopwatch stopwatch = new Stopwatch();//Makes use of QueryPerformanceCounter WIN32 API
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < milliseconds)
{
//So we don't burn cpu cycles
if ((milliseconds - stopwatch.ElapsedMilliseconds) > 20)
{
Thread.Sleep(5);
}
else
{
Thread.Sleep(1);
}
}
stopwatch.Stop();
//Set it back to normal.
TimeEndPeriod(1);
}