Maison > Article > développement back-end > Introduction détaillée à C#Thread petit à petit
Création d'une minuterie simple en utilisant Thread de C#. Afin de vous permettre de faire une pause après 45 minutes, une invite musicale retentira après 45 minutes.
La méthode de soustraction TimeSpan utilisée au début est écrite comme ceci dans la fonction de démarrage de Thread :
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; } } } } }
Plus tard, j'ai découvert Cette méthode est trop inefficace. Bien sûr, vous pouvez utiliser Thread.Sleep(20) ; cette fonction pour réduire le temps d'utilisation du processeur. En fait, l'ajout de Thread.Sleep(20); au milieu peut réduire considérablement la consommation du processeur. Plus tard, j'ai découvert que Thread en C# avait sa propre fonction join(), qui peut faire attendre le thread pendant un certain temps. La méthode d'appel est la suivante
th.Join(new TimeSpan(hours, minutes, seconds)); Pendant la période d'attente, le thread est dans WaitSleepJoinstate.
Bien sûr, vous pouvez également appeler Thread.Sleep(millionseconds); voici la différence entre Sleep et Join
Lorsque le thread exécute Sleep, le système quitte la file d'attente d'exécution Après un certain temps, lorsque la veille se termine, le système génère une interruption d'horloge, provoquant le retour du thread dans la file d'attente d'exécution pour reprendre l'exécution du thread. Si le paramètre de la méthode Sleep est 0, cela signifie que ce thread doit être suspendu pour laisser d'autres threads en attente s'exécuter ici, et il se peut aussi que ce soit le programme qui vient d'être exécuté. Cela entraînera une utilisation du processeur toujours à 100 %. Parfois votre interface est morte, mais vous pouvez toujours déplacer la souris. S'il s'agit de Timeout.Infinite, cela signifie que le thread dormira jusqu'à ce qu'il soit interrompu par un autre thread qui appelle Thread.Interrupt ou soit abandonné par Thread.Abort.
Si le fil parent se termine avant le fil enfant, le fil enfant sera forcé de se terminer en même temps que le fil parent se termine. La méthode Thread.Join() fait attendre le thread parent jusqu'à la fin du thread enfant. La méthode Join a une valeur de retour Lorsque la valeur est vraie, cela signifie que le thread est terminé. Si faux, cela signifie que le thread ne s'est pas terminé après avoir attendu cette période. Si le thread est dans l'état Non démarré, l'appel de join() provoquera une exception ThreadStateException. Si le thread est terminé, l'appel de cette fonction obtiendra immédiatement la valeur de retour.
Par exemple, le programme principal suivant
... ThreadStart st = New ThreadStart(fun); Thread th = new Thread(ThreadStart st); th.Start(); Application.Exit(); ... //下面是fun函数 void fun() { while(true) { ... } }
Le seul problème de ce programme est qu'il est possible qu'après le programme principal se termine, le thread esclave n'est pas encore terminé. (Ce fil d'esclave est tellement pitoyable...)
Au fait, voici quelques statuts du fil :
Création : Lorsqu'un nouveau processus est créé, un fil de discussion est également créé pour le processus. Les threads peuvent également créer de nouveaux threads.
Prêt : Le thread a obtenu toutes les ressources sauf le processeur.
En cours d'exécution : le thread est en cours d'exécution sur le processeur.
Bloqué : Le fil de discussion est suspendu en raison de l'attente d'un événement .
Résiliation : un fil de discussion est terminé.
Mais il y a plusieurs autres états dans le fil de discussion C# :
Aborted, AbortRequested, Background, Running, Stopped, StopRequested, Suspended, SuspendRequested, Unstarted, WaitSleepJoin.
Abort() entraînera ThreadState.AbortRequested. Une fois que le thread qui appelle Abort() aura pris le contrôle, cela entraînera ThreadState.Aborted. La différence entre AbortRequested et Aborted est que l'un est arrêté et l'autre ne l'est pas. . Arrêté signifie que le thread est terminé. Cependant, j'ai essayé et testé plusieurs fois et j'ai constaté que lorsque la fonction Abort() est appelée, l'état du thread passe à Arrêté. La manière de le faire passer à l'état Aborted est encore à l'étude. Les autres États sont similaires. L'appel de la fonction correspondante générera une demande de statut correspondante, et il faudra un certain temps pour obtenir le statut correspondant. Quant à Unstarted, cela signifie que la fonction Start() n'a pas été appelée et Running est le résultat de l'appel de la fonction Start() ou Resume(). WaitSleepJoin attend les E/S ou appelle la méthode Join(). La différence entre les méthodes Join() et Sleep() ici est que l'appel de l'état du thread Join() entre dans WaitSleepJoin, l'appel de l'état du thread Sleep() est toujours en cours d'exécution.
La méthode pour suspendre un thread est Suspend(); après avoir appelé cette méthode, le thread est dans l'état SuspendRequest. Si le thread exécute toujours la méthode join() après l'appel de Suspended(), car Suspended() nécessite que le thread atteigne le point sûr avant de pouvoir suspendre le thread à ce moment, l'état du thread. est SuspendRequested|WaitSleepJoin . Mais le temps de la jointure ici compte toujours. Je ne sais donc toujours pas quelle méthode utiliser pour suspendre le nombre de jointures. Bien sûr, nous pouvons également résoudre le problème de la suspension complète du fil de discussion sans utiliser la jointure. Maintenant, je ne comprends pas quelle fonction Suspended() fait quoi, car le thread est toujours en cours d'exécution. Il convient également de mentionner que l'utilisation de Suspend() et de la méthode Resume() qui permet au thread de reprendre après avoir appelé Suspend() est désormais obsolète. La raison est très simple, car ces deux méthodes sont exécutées par d'autres threads, et les autres threads ne peuvent pas connaître avec précision l'état du thread étant Suspend(), comme la structure d'une certaine classe Function délai d'exécution, ou destruction, etc. Il est donc dangereux d'utiliser cette fonction pour la synchronisation.
De plus, il convient de noter que le n de Thread.Sleep(n) ne peut pas contrôler l'heure avec précision. Si vous réfléchissez au temps nécessaire au thread, il y a un problème avec ce contrôle. Si le thread actuel est un thread de premier plan, alors Thread.Sleep(n) doit être supérieur à n avant de pouvoir se fermer. S'il s'agit d'un processus en arrière-plan, lorsque le programme principal se termine, le thread ne peut plus être réveillé... misérable... il est donc généralement recommandé de ne pas utiliser la fonction Thread.Sleep(). De plus, la fonction Sleep ne peut pas être utilisée pour la synchronisation. Peter a déclaré que la fonction Sleep du programme était de mauvaise conception.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!