J'utilise le code ci-dessous pour créer plusieurs tâches dans C #: Je rencontre un comportement étrange dans le code ci-dessus. En mettant un point d'arrêt à la ligne _tasklist.add (tâche.run ((() => TaskMethod1 (UsalCred))); Code>, je vérifie la valeur de
UserCred code> chaque fois
TaskMethod1 code> est appelé et il n'est pas null tout en étant appelé mais dans l'un des cas, la valeur de
userCred code> est
null code> intérieure
TaskMethod1 code >. Je n'ai aucune idée de la façon dont cela pourrait se produire. P> p>
3 Réponses :
Vous utilisez la tâche Vous devez utiliser P> .Run code> où dans vous utilisez des variables à partir de la boucle. Vous n'en passez pas à la tâche. Donc, au moment où la tâche de temps exécute, sa valeur est modifiée.
while (runningService)
{
string usercred;
// This will create more than one task in parallel to run,
// and each task can take upto 30 minutes to finish.
while (cred.TryDequeue(out usercred))
{
_taskList.Add(Task.Factory.StartNew((data) => TaskMethod1(data.ToString()), usercred)
}
}
Utilisation de la méthode code> Task.Factory.StartNew Code> au lieu de Tâche.Run Code> Pour la raison de passer un argument est considéré une technique d'optimisation des performances (évite les fermetures pour les chemins de code sensibles à la performance). Pour le code d'application normal, la tâche
.Run code> est préférable car il est plus lisible.
Le changement suivant a résolu le problème.
private static void TaskMethod() { while(runningService) { string usercred; // This will create more than one task in parallel to run, // and each task can take up to 30 minutes to finish. while(cred.TryDequeue(out usercred)) { var uc = usercred; _taskList.Add(Task.Run(() => TaskMethod1(uc))); } } }
La réponse d'une theodor résout le problème. Votre code réutilisait la même référence à userCred code> donc si la tâche n'a pas démarré assez rapidement le prochain
creefreeeue (Out UserCref) code> écraserait la valeur de
UsaterCrred code>. Qu'est-ce qui a fait
null code> est toujours un mystère pour moi. Mais j'étais curieux si ma suggestion fonctionnerait et cela le faisait.
Vous devriez userCred code> variable à l'intérieur de l'intérieur
pendant code> boucle, de sorte que la Lambda à l'intérieur de la tâche code> Capture une variable distincte pour chaque boucle, et non la même variable pour toutes les boucles.
while(runningService)
{
while(cred.TryDequeue(out var usercred))
{
_taskList.Add(Task.Run(() => TaskMethod1(usercred)));
}
}
Je soupçonne que vous avez Problème de variable capturé . Veuillez ajouter du code qui affiche tous les usages de la variable arg1 i> inside méthode TaskMethod i>.
Édité avec le code indiquant l'utilisation de la variable à l'intérieur du Taskmethod.
Pouvez-vous s'il vous plaît changer
tandis que (cred.tryDequeue (Out UserCred)) {_tasklist.add (tâche.run ((((() => TaskMethod1 (Usalcred))); } code> à
tandis que (cred.tryDequeue (Out UskCred)) {var uc = Usalcred; _tasklist.add (tâche.run ((() => TaskMethod1 (UC))); } code> et laissez-nous savoir si le problème disparaît?
Est-ce qu'un problème ne se produit que lorsque le débogueur est attaché et disparaît lorsque vous exécutez votre programme avec CTRL + F5 (sans débogage)? Je demande parce que vous avez mentionné un point d'arrêt et que le débogueur n'a pas 100% digne de confiance avec un code multithread.
Savez-vous également que la méthode
TaskMethod code> crée une boucle serrée?
Désolé, @theodorzoulias mais qu'entendez-vous par boucle serrée?
Le
trydeffeue code> retournera
FALSE code> la plupart du temps, le thread continuera de filer non-stop, dans essentiellement un
{} code> boucle.
Oui, il y a des conditions à ne pas laisser cela arriver, j'ai mis. Mais cela ne peut pas la raison du problème que je suis confronté à droite ou peut-être?
Non, c'est certainement sans rapport. Mais je devais le mentionner car il y a des moyens moins chers de produire de la chaleur que d'utiliser des cœurs de cpu filant. :-)
@Enigmativité, il semble avoir travaillé ce que vous avez suggéré, mais je ne suis toujours pas sûr de la raison, pouvez-vous s'il vous plaît expliquer pourquoi cela? (Je suis le stress le test, mais il a passé les tests de base.)