it-swarm-tr.com

C # programımı 50 msn boyunca uykuya nasıl sokarım?

C # programımın 50 milisaniye boyunca uyumasını nasıl sağlayabilirim?

Bu kolay bir soru gibi görünebilir, ancak geçici bir beyin yetmezliği anı yaşıyorum!

263
TK.
System.Threading.Thread.Sleep(50);

Ancak, ana GUI iş parçacığında bunu yapmanın GUI'nizin güncellenmesini engelleyeceğini unutmayın ("durgun" olacak)

VB.net için de çalışması için ; komutunu kaldırın.

315
Isak Savo

Herhangi bir programlama dilinde (neredeyse) beklemek için temelde 3 seçenek vardır:

  1. Gevşek beklemede
    • Iş parçacığı bloklarını belirli bir süre için yürütme (= işlem gücü tüketmiyor)
    • Engellenen/bekleyen iş parçacığında işlem mümkün değil
    • Çok kesin değil
  2. Sıkı bekletme (ayrıca sıkı döngü de denir)
    • i̇şlemci tüm bekleme süresi boyunca ÇOK meşgul (aslında, bir çekirdeğin işlem süresinin% 100'ünü tüketir)
    • Beklerken bazı işlemler yapılabilir
    • Çok hassas
  3. Kombinasyon önceki 2/
    • Genellikle 1. işlem verimliliğini ve 2 + işlem yapabilen kesinliği + yeteneği birleştirir.

1 için. - C #’da gevşek bekleme:

Thread.Sleep(numberOfMilliseconds);

Bununla birlikte, windows thread zamanlayıcı, Sleep() değerinin 15ms civarında olmasına neden olur (bu nedenle yalnızca 1ms için beklemek üzere planlanmış olsa bile Sleep, 20ms için kolayca bekleyebilir).

2 için. - 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 başka bir zaman ölçüm aracı da kullanabiliriz, ancak Stopwatch çok daha hızlı (ve bu gerçekten sıkı döngüde görünebilir).

için - 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 1ms (veya işletim sistemi iplik programlamasına bağlı olarak biraz daha fazla) iş parçacığını engeller, bu nedenle işlemci bu engelleme süresi için meşgul değildir ve kod işlemcinin gücünün% 100'ünü tüketmez. Diğer işlemler engelleme arasında hala yapılabilir (örneğin: kullanıcı arayüzünün güncellenmesi, olayların ele alınması veya etkileşim/iletişim malzemelerinin yapılması).

147
Thetam

Windows'ta bir tam uyku zamanını belirtemezsiniz. Bunun için gerçek zamanlı bir işletim sistemine ihtiyacınız var. Yapabileceğiniz en iyi şey minimum uyku zamanını belirlemektir. O zaman bundan sonra ipliğini uyandırmak zamanlayıcıya kalmış. Ve asla GUI iş parçacığında .Sleep() öğesini çağırın.

54
Joel Coehoorn

Şimdilik zaman uyumsuzluk/bekletme özelliğine sahip olduğunuzdan, 50ms için uyumanın en iyi yolu Task.Delay kullanmaktır:

async void foo()
{
    // something
    await Task.Delay(50);
}

Veya .NET 4'ü hedefliyorsanız (VS2010 veya Microsoft.Bcl.Async için Async CTP 3 ile), şunları kullanmanız gerekir:

async void foo()
{
    // something
    await TaskEx.Delay(50);
}

Bu şekilde, UI iş parçacığını engellemeyeceksiniz.

44
Toni Petrina

Bu kodu kullan

using System.Threading;
// ...
Thread.Sleep(50);
31
Thread.Sleep(50);

İş parçacığı, işletim sistemi tarafından belirtilen süre boyunca yürütülecek şekilde zamanlanmamış. Bu yöntem, iş parçacığının durumunu WaitSleepJoin içerecek şekilde değiştirir.

Bu yöntem standart COM ve SendMessage pompalamasını gerçekleştirmez. STAThreadAttribute olan bir iş parçacığı üzerinde uyumanız gerekiyor, ancak standart COM ve SendMessage pompalama yapmak istiyorsanız, bir zaman aşımı aralığı belirten Join yönteminin aşırı yüklemelerinden birini kullanmayı düşünün.

Thread.Join
14
SelvirK
Thread.Sleep
10
Roger Lipscombe

Okunabilirlik için:

using System.Threading;
Thread.Sleep(TimeSpan.FromMilliseconds(50));
3
Colonel Panic

.NET Framework 4.5 ile başlayarak, şunları kullanabilirsiniz:

using System.Threading.Tasks;

Task.Delay(50).Wait();   // wait 50ms
0
timmebee

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);
    }
0
Akumaburn