it-swarm-id.com

Bagaimana caranya agar program C # saya tidur selama 50 msec?

Bagaimana caranya agar program C # saya tidur selama 50 milidetik?

Ini mungkin pertanyaan yang mudah, tetapi saya mengalami kegagalan otak sementara!

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

Ingat juga, bahwa melakukan ini di utas GUI utama akan memblokir GUI Anda dari pembaruan (akan terasa "lamban")

Hapus saja ; untuk membuatnya berfungsi untuk VB.net juga.

315
Isak Savo

Pada dasarnya ada 3 pilihan untuk menunggu (hampir) bahasa pemrograman:

  1. Longgar menungg
    • Menjalankan blok ulir untuk waktu tertentu (= tidak mengkonsumsi daya pemrosesan)
    • Tidak ada pemrosesan yang dimungkinkan pada utas yang diblokir/menunggu
    • Tidak terlalu tepat
  2. menunggu ketat (juga disebut loop ketat)
    • prosesor SANGAT sibuk untuk seluruh interval menunggu (pada kenyataannya, biasanya menghabiskan 100% dari waktu pemrosesan satu inti)
    • Beberapa tindakan dapat dilakukan sambil menunggu
    • Sangat tepat
  3. Kombinasi dari 2 sebelumnya
    • Biasanya menggabungkan efisiensi pemrosesan 1. dan ketepatan + kemampuan untuk melakukan sesuatu 2.

ntuk 1. - Longgar menunggu di C #:

Thread.Sleep(numberOfMilliseconds);

Namun, penjadwal thread Windows menyebabkan akurasi Sleep() menjadi sekitar 15ms (jadi Sleep dapat dengan mudah menunggu selama 20ms, bahkan jika dijadwalkan untuk menunggu hanya selama 1ms).

ntuk 2. - Ketat menunggu di C # adalah:

Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
    //some other processing to do possible
    if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
    {
        break;
    }
}

Kita juga bisa menggunakan DateTime.Now atau cara pengukuran waktu lainnya, tetapi Stopwatch jauh lebih cepat (dan ini akan benar-benar terlihat dalam loop ketat).

ntuk 3. - Kombinasi:

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
}

Kode ini secara teratur memblokir utas untuk 1 ms (atau sedikit lebih, tergantung pada penjadwalan utas OS), sehingga prosesor tidak sibuk untuk waktu pemblokiran dan kode tidak menghabiskan 100% daya prosesor. Pemrosesan lainnya masih dapat dilakukan di antara pemblokiran (seperti: memperbarui UI, menangani acara atau melakukan hal-hal interaksi/komunikasi).

147
Thetam

Anda tidak dapat menentukan waktu tidur tepat di Windows. Anda memerlukan OS waktu nyata untuk itu. Yang terbaik yang dapat Anda lakukan adalah menentukan waktu tidur minimum . Kemudian terserah pada penjadwal untuk membangunkan utas Anda setelah itu. Dan tidak pernah panggil .Sleep() pada utas GUI.

54
Joel Coehoorn

Karena sekarang Anda memiliki fitur async/menunggu, cara terbaik untuk tidur selama 50 ms adalah dengan menggunakan Task.Delay:

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

Atau jika Anda menargetkan .NET 4 (dengan Async CTP 3 untuk VS2010 atau Microsoft.Bcl.Async), Anda harus menggunakan:

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

Dengan cara ini Anda tidak akan memblokir utas UI.

44
Toni Petrina

Gunakan kode ini

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

Utas tidak akan dijadwalkan untuk dieksekusi oleh sistem operasi untuk jumlah waktu yang ditentukan. Metode ini mengubah status utas untuk menyertakan WaitSleepJoin.

Metode ini tidak melakukan pemompaan COM dan SendMessage standar. Jika Anda perlu tidur di utas yang memiliki STAThreadAttribute, tetapi Anda ingin melakukan pemompaan COM dan SendMessage standar, pertimbangkan untuk menggunakan salah satu kelebihan metode Join yang menentukan interval waktu habis.

Thread.Join
14
SelvirK
Thread.Sleep
10
Roger Lipscombe

Untuk keterbacaan:

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

Dimulai dengan .NET Framework 4.5, Anda dapat menggunakan:

using System.Threading.Tasks;

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

Terbaik dari kedua dunia:

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