Как мне заставить мою программу на C # спать 50 миллисекунд?
Это может показаться простым вопросом, но у меня временная остановка мозга!
Как мне заставить мою программу на C # спать 50 миллисекунд?
Это может показаться простым вопросом, но у меня временная остановка мозга!
Ответы:
System.Threading.Thread.Sleep(50);
Помните, однако, что выполнение этого в основном потоке GUI заблокирует обновление вашего GUI (оно будет выглядеть «вялым»)
Просто удалите ;
чтобы он работал и для VB.net.
Есть в основном 3 варианта ожидания на (почти) любом языке программирования:
для 1. - Слабое ожидание в C #:
Thread.Sleep(numberOfMilliseconds);
Тем не менее, планировщик потока Windows вызывает точность Sleep()
к тому, что точность составляет около 15 мс (так что Sleep может легко ждать 20 мс, даже если запланировано ожидание только 1 мс).
для 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 мс (или чуть больше, в зависимости от планирования потоков ОС), поэтому процессор не занят в это время блокировки и код не потребляет 100% мощности процессора. Между ними может выполняться другая обработка (например, обновление пользовательского интерфейса, обработка событий или выполнение взаимодействия / взаимодействия).
Вы не можете указать точное время сна в Windows. Для этого вам нужна ОС реального времени. Лучшее, что вы можете сделать, это указать минимальное время сна. Тогда это до планировщика, чтобы разбудить Ваш поток после этого. И никогда не вызывайте .Sleep()
на поток GUI.
Поскольку теперь у вас есть функция async / await, лучший способ спать в течение 50 мс - использовать Task.Delay:
async void foo()
{
// something
await Task.Delay(50);
}
Или, если вы ориентируетесь на .NET 4 (с Async CTP 3 для VS2010 или Microsoft.Bcl.Async), вы должны использовать:
async void foo()
{
// something
await TaskEx.Delay(50);
}
Таким образом, вы не будете блокировать поток пользовательского интерфейса.
FlushAsync
версия.
async
объявления, является вызовTask.Delay(50).Wait();
Используйте этот код
using System.Threading;
// ...
Thread.Sleep(50);
Thread.Sleep(50);
Поток не будет запланирован для выполнения операционной системой в течение указанного времени. Этот метод изменяет состояние потока, чтобы включить WaitSleepJoin.
Этот метод не выполняет стандартную перекачку COM и SendMessage. Если вам нужно спать в потоке с атрибутом STAThreadAttribute, но вы хотите выполнить стандартную откачку COM и SendMessage, рассмотрите возможность использования одной из перегрузок метода Join, которая задает интервал времени ожидания.
Thread.Join
Для удобства чтения:
using System.Threading;
Thread.Sleep(TimeSpan.FromMilliseconds(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);
}