Question

J'ai récemment essayé d'utiliser backgroundworker au lieu de "classique". et je me rends compte que cela cause, au moins pour moi, plus de problèmes que de solutions. J'ai un travailleur d'arrière-plan qui exécute une lecture synchrone (dans ce cas, à partir de serialPort) et qui est bloqué pendant environ 30 secondes dans une ligne de code, puis l'annulation des dépenses n'est pas la solution. Je constate que si l'application est fermée à ce stade (soit avec le bouton en croix et Application.Exit ()), le processus conserve zombie pour toujours.

J'ai besoin d'un moyen de forcer l'abandon ou de tuer le thread d'arrière-plan.

Était-ce utile?

La solution

Je ne suis pas très sûr de ce que vous essayez d'accomplir, mais peut-être que le SerialPort.DataReceived est-il une meilleure solution?

Si vous maîtrisez déjà l'utilisation des threads, je ne vois pas l'intérêt d'utiliser BackgroundWorker. Il est conçu pour les personnes qui ne comprennent pas les discussions au départ.

En outre, je n’aime pas l’idée d’avorter un fil. Cela semble dangereux et les applications multithread n'ont plus besoin de prendre de risques.

Autres conseils

Je mets un ensemble qui (je pense) fait le travail. S'il vous plaît laissez-moi savoir si im waaaay off. Voici un exemple simple de son fonctionnement.

var backgroundWorker = new BackgroundWorker(){WorkerSupportsCancellation = true};

backgroundWorker.DoWork += (sender, args) =>
         {                 
                 var thisWorker = sender as BackgroundWorker;
                 var _child = new Thread(() =>
                                               {
                                                   //..Do Some Code

                                               });
                 _child .Start();
                 while (_child.IsAlive)
                 {
                     if (thisWorker.CancellationPending)
                     {
                         _child.Abort();
                         args.Cancel = true;
                     }
                     Thread.SpinWait(1);
                 }                 
         };

 backgroundWorker.RunWorkerAsync(parameter);
 //..Do Something...
backgroundWorker.CancelAsync();

Étant donné que le travailleur d’arrière-plan fait partie du pool de threads, nous ne voulons pas l’abandonner. Mais nous pouvons exécuter un thread en interne sur lequel nous pouvons autoriser un abandon. BackgroundWorker s’exécute ensuite jusqu’à ce que le thread enfant soit terminé ou que nous lui signalions de mettre fin au processus. Le thread de travail en arrière-plan peut ensuite revenir dans le pool de lecture. En règle générale, je vais envelopper ceci dans une classe d'assistance et passer par la méthode déléguée que je veux que le thread en arrière-plan exécute soit transmise en tant que paramètre, puis dans le thread enfant.

S'il vous plaît, faites-le-moi savoir si je me tape la tête contre un mur, mais cela semble bien fonctionner .. Mais le problème avec les fils n'est-ce pas? p>

Le processus ne doit pas devenir un zombie, car le fil de discussion BackgroundWorker est marqué comme "arrière-plan". et devrait se terminer lorsque l’UI est fermée.

Je ne pense pas que BackgroundWorker prenne en charge la suppression du fil. L'annulation d'une opération doit être effectuée dans la méthode qui effectue le travail. Dans votre cas, je pense qu'un fil régulier sera la meilleure option.

Vous pouvez essayer ceci:

            backgroundworker.Dispose();
            backgroundworker = null;
            GC.Collect(); //this helps cleans up ram
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top