it-swarm.com.de

Wie kann ich mein C # -Programm für 50 ms in den Ruhezustand versetzen?

Wie kann ich mein C # -Programm für 50 Millisekunden in den Ruhezustand versetzen?

Dies scheint eine einfache Frage zu sein, aber ich habe einen vorübergehenden Moment des Gehirnversagens!

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

Denken Sie jedoch daran, dass dies im Haupt-GUI-Thread die Aktualisierung Ihrer GUI blockiert (es wird sich "träge" anfühlen).

Entfernen Sie einfach das ;, damit es auch für VB.net funktioniert.

315
Isak Savo

Grundsätzlich gibt es 3 Möglichkeiten, in (fast) jeder Programmiersprache zu warten:

  1. Loses Warten
    • Thread-Blöcke für eine bestimmte Zeit ausführen (= verbraucht keine Rechenleistung)
    • Bei blockiertem/wartendem Thread ist keine Verarbeitung möglich
    • Nicht so genau
  2. Enges Warten (auch als enge Schleife bezeichnet)
    • der Prozessor ist während des gesamten Warteintervalls SEHR beschäftigt (tatsächlich verbraucht er normalerweise 100% der Verarbeitungszeit eines Kerns).
    • Einige Aktionen können während des Wartens ausgeführt werden
    • Sehr präzise
  3. Kombination der vorherigen 2
    • Es kombiniert normalerweise die Verarbeitungseffizienz von 1. und die Genauigkeit + die Fähigkeit, etwas von 2 zu tun.

für 1. - Loses Warten in C #:

Thread.Sleep(numberOfMilliseconds);

Windows Thread Scheduler bewirkt jedoch, dass die Genauigkeit von Sleep() etwa 15 ms beträgt (so dass der Ruhezustand problemlos 20 ms warten kann, auch wenn geplant ist, nur 1 ms zu warten).

für 2. - Enges Warten in C # ist:

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

Wir könnten auch DateTime.Now Oder andere Mittel zur Zeitmessung verwenden, aber Stopwatch ist viel schneller (und dies würde in einer engen Schleife wirklich sichtbar werden).

für 3. - Kombination:

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
}

Dieser Code blockiert Threads regelmäßig für 1 ms (oder etwas mehr, abhängig von der Thread-Planung des Betriebssystems), sodass der Prozessor für diese Zeit des Blockierens nicht beschäftigt ist und der Code nicht 100% der Prozessorleistung verbraucht. Zwischendurch kann noch eine andere Verarbeitung durchgeführt werden (z. B. Aktualisierung der Benutzeroberfläche, Behandlung von Ereignissen oder Durchführung von Interaktions-/Kommunikationsaufgaben).

147
Thetam

Sie können in Windows keine genaue Ruhezeit angeben. Sie benötigen dafür ein Echtzeit-Betriebssystem. Geben Sie am besten eine Mindestruhezeit an. Dann ist es an der Zeitplanung, Ihren Thread danach aufzuwecken. Und nie.Sleep() im GUI-Thread aufrufen.

54
Joel Coehoorn

Da Sie jetzt über die Funktion "Async/Warten" verfügen, können Sie 50 ms lang am besten mit Task.Delay schlafen.

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

Wenn Sie .NET 4 als Ziel haben (mit Async CTP 3 für VS2010 oder Microsoft.Bcl.Async), müssen Sie Folgendes verwenden:

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

Auf diese Weise wird der UI-Thread nicht blockiert.

44
Toni Petrina

Verwenden Sie diesen Code

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

Der Thread wird für die angegebene Zeitspanne nicht für die Ausführung durch das Betriebssystem geplant. Diese Methode ändert den Status des Threads, um WaitSleepJoin einzuschließen.

Diese Methode führt kein Standard-COM- und SendMessage-Pumpen durch. Wenn Sie in einem Thread mit STAThreadAttribute schlafen müssen, aber Standard-COM- und SendMessage-Pumping ausführen möchten, sollten Sie eine der Überladungen der Join-Methode verwenden, die ein Zeitlimitintervall angibt.

Thread.Join
14
SelvirK
Thread.Sleep
10
Roger Lipscombe

Zur besseren Lesbarkeit:

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

Ab .NET Framework 4.5 können Sie Folgendes verwenden:

using System.Threading.Tasks;

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

Beste aus beiden Welten:

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