Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Einführung in C#Thread Stück für Stück

Detaillierte Einführung in C#Thread Stück für Stück

黄舟
黄舟Original
2017-03-20 13:17:171836Durchsuche

Einen einfachen Timer mit Thread von C# erstellt. Um Ihnen nach 45 Minuten eine Pause zu ermöglichen, ertönt nach 45 Minuten eine Musikansage.

Die am Anfang verwendete TimeSpan-Subtraktionsmethode wird in der Startfunktion von Thread wie folgt geschrieben:

  1. public void CountTime()
    {
                
       while (true)
       {
          TimeSpan tsNew = new TimeSpan(DateTime.Now.Ticks);
          TimeSpan tsIn = tsNew - tsOld;
          if (tsIn.Minutes >= 1)
          {
        
             while (true)
             {
                 TimeSpan tsNewer = new TimeSpan(DateTime.Now.Ticks);
                 TimeSpan tsIner = tsNewer - tsNew;
                 if (tsIner.Minutes >= 10)
                 {
                    //十分钟后线程重启
                     tsOld = tsNew;
                     break;
                 }
             }
             
           }
       }
    }

Später habe ich es herausgefunden Diese Methode ist zu ineffizient. Natürlich können Sie Thread.Sleep(20); diese Funktion verwenden, um die CPU-Nutzungszeit zu reduzieren. Tatsächlich kann das Hinzufügen von Thread.Sleep(20); in der Mitte den CPU-Verbrauch erheblich reduzieren. Später entdeckte ich, dass Thread in C# über eine eigene Funktion join() verfügt, die den Thread eine Zeit lang warten lassen kann. Die aufrufende Methode lautet wie folgt:

th.Join(new TimeSpan(hours, minutes, seconds)); Während der Wartezeit befindet sich der Thread im WaitSleepJoinZustand.

Natürlich können Sie auch Thread.Sleep(millionseconds) aufrufen; hier ist der Unterschied zwischen Sleep und Join

Wenn der Thread Sleep ausführt, wird das System Verlässt die Ausführungswarteschlange. Nach einer Weile, wenn der Ruhezustand endet, generiert das System einen Taktinterrupt, wodurch der Thread zur Ausführungswarteschlange zurückkehrt und die Ausführung des Threads fortsetzt. Wenn der Parameter der Sleep-Methode 0 ist, bedeutet dies, dass dieser Thread angehalten werden sollte, damit andere wartende Threads ausgeführt werden können. Die CPU wird hier die Kontrolle neu verteilen, und es kann auch das Programm sein, das gerade ausgeführt wurde. Auf diese Weise beträgt die CPU-Auslastung immer 100 %. Manchmal ist Ihre Benutzeroberfläche tot, aber Sie können die Maus trotzdem bewegen. Wenn es Timeout.Infinite ist, bedeutet dies, dass der Thread schläft, bis er von einem anderen Thread unterbrochen wird, der Thread.Interrupt aufruft, oder von Thread.Abort abgebrochen wird.
 
Wenn der übergeordnete Thread vor dem untergeordneten Thread endet, wird der untergeordnete Thread gezwungen, gleichzeitig mit dem Ende des übergeordneten Threads zu enden. Die Thread.Join()-Methode bewirkt, dass der übergeordnete Thread wartet, bis der untergeordnete Thread endet. Die Join-Methode hat einen Rückgabewert. Wenn der Wert wahr ist, bedeutet dies, dass der Thread beendet ist. Bei „false“ bedeutet dies, dass der Thread nach dieser Wartezeit nicht beendet wurde. Wenn sich der Thread im Status „Ungestartet“ befindet, führt der Aufruf von „join()“ zu einer ThreadStateException-Ausnahme. Wenn der Thread beendet wurde, wird beim Aufruf dieser Funktion sofort der Rückgabewert abgerufen.

Zum Beispiel das folgende Hauptprogramm

...
ThreadStart st = New ThreadStart(fun);
Thread th = new Thread(ThreadStart st);
th.Start();
Application.Exit();
...
 
//下面是fun函数
void fun()
{
    while(true)
    {
            ...
    }
}

Das einzige Problem mit diesem Programm ist, dass es möglich ist, dass danach Das Hauptprogramm wird beendet. Der Slave-Thread ist noch nicht beendet. (Dieser Sklaventhread ist so erbärmlich...)

Hier übrigens ein paar Status des Threads:

Erstellung: Wenn ein neuer Prozess erstellt wird, wird auch ein Thread für den Prozess erstellt. Threads können auch neue Threads erstellen.

Bereit: Der Thread hat alle Ressourcen außer dem Prozessor erhalten.

Läuft: Der Thread wird auf dem Prozessor ausgeführt.

Blockiert: Der Thread wurde angehalten, da auf ein Ereignis gewartet wurde.

Beendigung: Ein Thread wurde abgeschlossen.

Aber es gibt noch mehrere weitere Zustände im C#-Thread:

Aborted, AbortRequested, Background, Running, Stopped, StopRequested, Suspended, SuspendRequested, Unstarted, WaitSleepJoin.

Abort() führt zu ThreadState.AbortRequested. Nachdem der Thread, der Abort() aufruft, die Kontrolle erlangt, wird ThreadState.Aborted verursacht. Der Unterschied zwischen AbortRequested und Aborted besteht darin, dass einer gestoppt wird und der andere nicht . Gestoppt bedeutet, dass der Thread beendet ist. Ich habe es jedoch viele Male ausprobiert und festgestellt, dass sich der Thread-Status beim Aufruf der Funktion Abort() in „Gestoppt“ ändert. Wie es in den Aborted-Zustand versetzt werden kann, wird noch untersucht. Die anderen Staaten sind ähnlich. Durch Aufrufen der entsprechenden Funktion wird eine entsprechende Statusanforderung generiert, und es wird eine Weile dauern, bis der entsprechende Status abgerufen wird. Bei Unstarted wurde die Funktion Start() nicht aufgerufen, und Running ist das Ergebnis des Aufrufs der Funktion Start() oder Resume(). WaitSleepJoin wartet auf E/A oder ruft die Join()-Methode auf. Der Unterschied zwischen den Methoden Join() und Sleep() besteht darin, dass der Aufruf des Thread-Status Join() in WaitSleepJoin wechselt und der Thread-Status beim Aufrufen von Sleep() noch ausgeführt wird.

Die Methode zum Anhalten eines Threads ist Suspend(); nach dem Aufruf dieser Methode befindet sich der Thread im SuspendRequest-Status. Wenn der Thread nach dem Aufruf von Suspended() immer noch die Methode join() ausführt, da Suspended() erfordert, dass der Thread den sicheren-Punkt erreicht, bevor er den Thread anhalten kann. Zu diesem Zeitpunkt der Thread-Status ist SuspendRequested|WaitSleepJoin . Aber die Uhr im Beitritt hier läuft noch. Daher weiß ich immer noch nicht, wie ich die Anzahl der Joins anhalten kann. Natürlich können wir das Problem des vollständigen Anhaltens des Threads auch ohne Verwendung von Join lösen. Jetzt verstehe ich nicht, welche Suspended()-Funktion was macht, da der Thread noch läuft. Erwähnenswert ist auch, dass die Verwendung von Suspend() und der Resume()-Methode, die es dem Thread ermöglicht, nach dem Aufruf von Suspend() wieder fortzufahren, jetzt veraltet ist. Der Grund ist sehr einfach, da diese beiden Methoden von anderen Threads ausgeführt werden und die anderen Threads den Status des Threads in Suspend() nicht genau kennen können, beispielsweise die -Struktur einer bestimmten Klasse Funktion Ausführungszeitraum oder Zerstörung usw. Daher ist es gefährlich, diese Funktion zur Synchronisierung zu verwenden.

Außerdem ist zu beachten, dass das n von Thread.Sleep(n) die Zeit nicht genau steuern kann. Wenn Sie bedenken, wie lange das Einfädeln dauert, liegt ein Problem mit dieser Steuerung vor. Wenn der aktuelle Thread ein Vordergrundthread ist, muss Thread.Sleep(n) größer als n sein, bevor er beendet werden kann. Wenn es sich um einen Hintergrundprozess handelt, kann der Thread beim Beenden des Hauptprogramms nicht mehr aktiviert werden ... miserabel ... daher wird generell empfohlen, die Funktion Thread.Sleep () nicht zu verwenden. Darüber hinaus kann die Sleep-Funktion nicht zur Synchronisierung verwendet werden. Peter sagte, dass die Sleep-Funktion des Programms ein schlechtes Design darstellt.


Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in C#Thread Stück für Stück. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn