BackgroundWorkers n'arrête jamais d'être occupé
for (do it a bunch of times)
{
while (backgroundWorker1.IsBusy && backgroundWorker2.IsBusy &&
backgroundWorker3.IsBusy && backgroundWorker4.IsBusy &&
backgroundWorker5.IsBusy)
{
System.Threading.Thread.Sleep(0001);
}
if (!backgroundWorker1.IsBusy)
{
backgroundWorker1.RunWorkerAsync();
}
else if (!backgroundWorker2.IsBusy)
{
backgroundWorker2.RunWorkerAsync();
}
else if (!backgroundWorker3.IsBusy)
{
backgroundWorker3.RunWorkerAsync();
}
else if (!backgroundWorker4.IsBusy)
{
backgroundWorker4.RunWorkerAsync();
}
else if (!backgroundWorker5.IsBusy)
{
backgroundWorker5.RunWorkerAsync();
}
}
il gère cinq fois (chaque BG-travailleur une fois) et se coince dans le temps. Ne pas le backgroundworkers jamais cesser d'être occupé ? comment puis-je vérifier la disponibilité ?
remarque: il y a 5 threads de travail, cela assure, aucun d'eux n'est jamais arrêté, toujours confier le travail à eux. Mais ils refusent de me dire quand ils sont disponibles, j'ai pensé qu'aurait une solution simple..
--[edit demande]---
En fait, c'était seulement un paramètre fictif, je l'ai enlevé et j'ai oublié de le sortir, je ne l'utilise que pour appeler la dowork, qui fait le sale boulot:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
timeconsumingfunction(publicstring);
}
Et la timeconsumingfunction N'fin. entrer dans dans le débogueur et l'exécution ligne par ligne, il va jusqu'au bout et arrive en finale '}'. Cela signifie qu'il se termine, non ?
---[EDIT RÉPONSE]----
il a travaillé par SIMPLEMENT remplacer la ligne
System.Threading.Thread.Sleep(0001);
avec
Application.DoEvents();
Je suppose que cela irait à l'arrière-plan, mais pas en recevoir la réponse et pas de mise à jour de la IsBusy balises.
Merci à tous, d'excellentes réponses, a beaucoup aidé!
source d'informationauteur Marcelo
Vous devez vous connecter pour publier un commentaire.
Votre boucle est à l'origine de l'impasse, l'BGWs ne peut pas terminer. Le problème est le RunWorkerCompleted cas, il est relevé sur le thread d'INTERFACE utilisateur. Que peu de BGW magie nécessite le thread d'INTERFACE utilisateur pour être libre, il doit être le pompage de la boucle de message. Problème, c'est le thread de l'INTERFACE utilisateur n'est pas inactif et il n'est pas de pompage des messages, il est coincé dans la boucle for. Ainsi, le gestionnaire d'événement ne peut pas s'exécuter et IsBusy reste fidèle.
Vous aurez besoin pour ce faire différemment. Tirer parti de la RunWorkerCompleted événement pour exécuter le code que vous auriez normalement à courir après cette boucle for. Résister à toute tentation d'Application d'appel.DoEvents() à l'intérieur de la boucle.
Je vous suggère de modifier votre code pour gérer le
RunWorkerCompleted
événement pour recevoir des notifications lorsque de votreBackgroundWorker
s aient terminé leur travail. Il y a un exemple d'utilisation de laBackgroundWorker
dans la documentation officielle.J'ai eu ce même problème lors de l'utilisation de tâches en arrière-plan et est venu à la conclusion que si vous utilisez la fonction sleep() dans une boucle, alors il sera coincé. Vous pouvez soit utiliser le RunWorkerCompleted de l'événement et de définir un indicateur booléen pour indiquer lors de chaque travailleur est fini.
Ou si vous voulez interrompre le fil que vous pouviez regarder à l'aide de threads au lieu de tâches en arrière-plan. Cependant, alors vous perdez la facilité d'utilisation en ce qui concerne les événements qui l'arrière-plan travailleur fournit.
Votre thread principal doit être de pompage des messages Windows (Application appelante.DoEvents dans ta boucle while, ou mieux encore par l'utilisation de Systèmes.De Windows.Les formulaires.Minuterie au lieu d'une boucle).
Si vous n'avez pas de pompe de messages de Windows, votre arrière-plan du travailleur "terminé" les notifications ne seront pas traitées, de sorte que le statut restera occupé.
J'ai eu un problème similaire, et ce que j'ai fait pour le résoudre était de joindre la fonction main avec un
try... catch... and finally...
déclaration.L' .IsBusy indique seulement que le backgroundworker est en fait de l'exécution d'une opération. Il sera occupé jusqu'à ce que "quelque chose" est terminé. Il semble que ce "quelque chose" n'est pas fini, en gardant votre backgroundworkers occupé.
De sorte qu'il serait utile si vous pouviez expliquer ce "quelque chose" est, et éventuellement combien de temps il faut pour faire "quelque chose" sur le thread principal.
Le problème est que, quoi que vous fassiez dans
worker.RunWorkerAsync()
n'est jamais fini. Peut-être qu'il est certaines boucle sans fin ou quelque chose comme ça définis dans votreDoWork
événement.Voici un exemple de travail, qui sélectionne la prochaine travailleur libre:
Une solution pour votre problème est donnée dans l'exemple ci-dessous. Comme Hans Passant expliqué votre code s'exécute dans le backgroundworker mais la RunWorkerCompleted de chaque thread n'est évaluée que dans le Thread de l'interface utilisateur. Pour ce faire, vous pouvez mettre en file d'attente à votre demande dans l'Isu de la file d'attente des threads, le pool de threads. De cette façon, l'INTERFACE utilisateur évalue la RunWorkerCompletedEvent et après que les sauts de retour à votre code.