C # programımı 50 milisaniye boyunca nasıl uykuya alabilirim?
Bu kolay bir soru gibi görünebilir, ancak geçici bir beyin yetmezliği anı yaşıyorum!
C # programımı 50 milisaniye boyunca nasıl uykuya alabilirim?
Bu kolay bir soru gibi görünebilir, ancak geçici bir beyin yetmezliği anı yaşıyorum!
Yanıtlar:
System.Threading.Thread.Sleep(50);
Yine de, bunu ana GUI iş parçacığında yapmanın GUI'nizin güncellenmesini engelleyeceğini unutmayın ("yavaş" hissedecektir)
;
VB.net için de çalışması için kaldırın .
Temel olarak herhangi bir programlama dilinde (neredeyse) beklemek için 3 seçenek vardır:
- C # için gevşek bekleme:
Thread.Sleep(numberOfMilliseconds);
Ancak, Windows iş parçacığı zamanlayıcı Sleep()
(bu nedenle, Uyku sadece 1ms beklemek üzere planlanmış olsa bile kolayca bekleyebilir).
- C # 'da sıkı bekleme:
Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
//some other processing to do possible
if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
{
break;
}
}
Ayrıca DateTime.Now
veya diğer zaman ölçüm yöntemlerini de kullanabiliriz , ancakStopwatch
çok daha hızlıdır (ve bu sıkı döngüde gerçekten görünür hale gelir).
3. - Kombinasyon:
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
}
Bu kod düzenli olarak 1 ms için iş parçacığını engeller (veya işletim sistemi iş parçacığı zamanlamasına bağlı olarak biraz daha fazla), bu nedenle işlemci bu engelleme süresi için meşgul değildir ve kod işlemci gücünün% 100'ünü tüketmez. Diğer işlemler yine de engelleme arasında gerçekleştirilebilir (örneğin: kullanıcı arayüzünün güncellenmesi, olayların işlenmesi veya etkileşim / iletişim şeylerinin yapılması).
Windows'da tam bir uyku zamanı belirleyemezsiniz . Bunun için gerçek zamanlı bir işletim sistemine ihtiyacınız var. Yapabileceğiniz en iyi şey minimum uyku süresini belirlemektir . Sonra bundan sonra iş parçacığını uyandırmak için zamanlayıcı kalmış. Ve asla.Sleep()
GUI iş parçacığını çağırmayın .
Artık eşzamansız / beklemede özelliğiniz olduğundan, 50ms boyunca uyumak için en iyi yol Görev kullanmaktır.
async void foo()
{
// something
await Task.Delay(50);
}
Veya .NET 4'ü (VS2010 veya Microsoft.Bcl.Async için Async CTP 3 ile) hedefliyorsanız aşağıdakileri kullanmalısınız:
async void foo()
{
// something
await TaskEx.Delay(50);
}
Bu şekilde UI iş parçacığını engellemezsiniz.
FlushAsync
versiyon olduğuna inanıyorum .
async
Beyan gerektirmeyen bir alternatif Task.Delay(50).Wait();
Bu kodu kullan
using System.Threading;
// ...
Thread.Sleep(50);
Thread.Sleep(50);
İş parçacığı, belirtilen süre boyunca işletim sistemi tarafından yürütülmesi için zamanlanmayacaktır. Bu yöntem, iş parçacığının durumunu WaitSleepJoin içerecek şekilde değiştirir.
Bu yöntem standart COM ve SendMessage pompalama gerçekleştirmez. STAThreadAttribute içeren bir iş parçacığı üzerinde uyumak gerekiyor, ancak standart COM ve SendMessage pompalama gerçekleştirmek istiyorsanız, bir zaman aşımı aralığı belirten Join yönteminin aşırı yüklerinden birini kullanmayı düşünün.
Thread.Join
Okunabilirlik için:
using System.Threading;
Thread.Sleep(TimeSpan.FromMilliseconds(50));
Her iki dünyanın en iyisi:
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);
}