2010-08-11 15 views
11

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?

+0

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

+0

Cela dépend de la façon dont vous l'avez mis en veille. – zneak

+1

Vous devez absolument nous dire au moins quel est le langage de programmation de cette question. – scy

Répondre

14

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(); 
3

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.

+0

@John, vous avez ajouté votre commentaire pendant que j'édiquais pour ajouter cette information :). –

+0

assez juste je vais retirer mon commentaire :) –

0

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.

1

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.

3
public void WakeUp() 
{ 
    if (Thread.CurrentThread.ThreadState == ThreadState.WaitSleepJoin) 
    Thread.CurrentThread.Interrupt(); 
} 
+1

Cela va abot le fil et ne pas le réveiller. – Danpe

+1

@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. –

+0

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