Dis que j'ai des articles 10n (j'ai besoin de les récupérer via le protocole HTTP), dans les tâches de code n sont démarrées pour obtenir des données, chaque tâche prend 10 éléments en séquence. Je mets les articles dans un Concurrentqueue
async Task<Item> GetItemAsync()
{
//fetch one item from the internet
}
async Task DoWork()
{
var tasks = new List<Task>();
var items = new ConcurrentQueue<Item>();
var handles = new List<ManualResetEvent>();
for i 1 -> N
{
var handle = new ManualResetEvent(false);
handles.Add(handle);
tasks.Add(Task.Factory.StartNew(async delegate
{
for j 1 -> 10
{
var item = await GetItemAsync();
items.Enqueue(item);
}
handle.Set();
});
}
//begin to process the items when any handle is set
WaitHandle.WaitAny(handles);
while(true)
{
if (all handles are set && items collection is empty) //***
break;
//in another word: all tasks are really completed
while(items.TryDequeue(out item))
{
AThreadUnsafeMethod(item); //process items one by one
}
}
}
3 Réponses :
Vous pouvez faire une serviette avec un délai d'attente de zéro pour vérifier l'état. Quelque chose comme ça devrait fonctionner: http: //msdn.microsoft.com/en-us/library/cc190477.aspx p> p>
"Bloque le thread actuel jusqu'à ce que l'instance actuelle reçoive un signal" de sorte que vous auriez 10 fils bloquants en attente de signal.
@Sebastian "Remarques: Si le délai d'attente est zéro, la méthode ne bloque pas. Il teste l'état de la poignée d'attente et retourne immédiatement."
@jaggedspire d'accord, c'est une information que j'ai manquée. Merci, c'est maintenant ma solution préférée pour vérifier les gauchons.
Eh bien, vous pourriez-vous em> construire cela vous-même, mais je pense que c'est des tonnes plus faciles avec TPL Dataflow . Quelque chose comme: p>
Merci tout. Enfin, j'ai trouvé CountDownEvent est très approprié pour ce scénario. L'implémentation générale ressemble à ceci: (pour les informations des autres)