Existe-t-il un moyen de réveiller un thread endormi en C#? Alors, l'a-t-il dormi pendant une longue période et l'a-t-il réveillé quand vous voulez que le travail soit traité?Y at-il un moyen de réveiller un fil de couchage?
Répondre
Un objet AutoResetEvent
(ou une autre mise en œuvre WaitHandle
) peut être utilisé pour dormir jusqu'à ce qu'un signal d'un autre fil est reçu:
// launch a calculation thread
var waitHandle = new AutoResetEvent(false);
int result;
var calculationThread = new Thread(
delegate
{
// this code will run on the calculation thread
result = FactorSomeLargeNumber();
waitHandle.Set();
});
calculationThread.Start();
// now that the other thread is launched, we can do something else.
DoOtherStuff();
// we've run out of other stuff to do, so sleep until calculation thread finishes
waitHandle.WaitOne();
Si votre thread est à l'intérieur d'un appel à Sleep
, il n'y a pas (habituellement) un moyen de le réveiller. (La seule exception que je connaisse est Java, qui permet de mettre fin à un arrêt anticipé si un autre thread appelle thread.interrupt()
.)
Le motif dont vous parlez semble appeler un événement: le thread contient une boucle, au sommet de laquelle il attend qu'un événement se déclenche. Si l'événement est actuellement désactivé, le thread "dort" jusqu'à ce qu'un autre thread déclenche l'événement. À ce stade, le fil de sommeil se réveille et continue son travail, jusqu'à la prochaine fois à travers la boucle quand il dort pour attendre un autre événement.
@John, vous avez ajouté votre commentaire pendant que j'édiquais pour ajouter cette information :). –
assez juste je vais retirer mon commentaire :) –
Est-ce que this allait aider? C# a good functionality pour la gestion des événements de thread. J'ai fait la plupart de mon travail en Python, mais C# semble avoir des bibliothèques solides pour le blocage des threads.
La meilleure solution serait d'utiliser des objets Task
avec la valeur par défaut TaskFactory
. Cette API (introduite dans .NET 4.0) utilise un pool de threads avec des files d'attente volantes et toutes ces choses fantaisistes.
Si .NET 4.0 n'est pas disponible, utilisez le ThreadPool
, qui a une file d'attente de travail intégrée (qui effectue un équilibrage de pool mais pas la même portée que le pool de threads 4.0).
Si vraiment vous devez le faire vous-même, alors je recommande un BlockingCollection<T>
, qui est une file d'attente de blocage de consommateur/producteur ajoutée dans .NET 4.0.
Si vous avez vraiment doit faire vous-même et ne peut pas utiliser .NET 4.0, vous pouvez utiliser un ManualResetEvent
ou AutoResetEvent
le long d'une file d'attente lock
-protected de travail.
public void WakeUp()
{
if (Thread.CurrentThread.ThreadState == ThreadState.WaitSleepJoin)
Thread.CurrentThread.Interrupt();
}
Cela va abot le fil et ne pas le réveiller. – Danpe
@Danpe Je doute qu'il annule le fil, alors quel serait le point de l'appeler une interruption. Lisez ceci: http://msdn.microsoft.com/en-us/library/system.threading.thread.interrupt(v=vs.110).aspx Vous devrez attraper l'exception. –
Ce n'est pas comme cela que vous accomplissez ce que le PO demande. Le code de thread lui-même devrait avoir un point d'attente définitif où il s'attend à ce que le système d'exploitation signale qu'il récupère le traitement du fil. Tout appel à 'Sleep' ou' SpinWait' ou 'Yield' placera le thread dans l'état' WaitSleepJoin'. – Slight
Dans quel réglage exactement? Nous aurions vraiment besoin de plus d'informations sur la plate-forme et/ou le modèle de threading que vous utilisez pour pouvoir y répondre de manière significative. – Gian
Cela dépend de la façon dont vous l'avez mis en veille. – zneak
Vous devez absolument nous dire au moins quel est le langage de programmation de cette question. – scy