2010-07-12 7 views
0

Normalement, quand je veux annuler un BackgroundWorker en C# Je ferai quelque chose comme ceci:C# BackgroundWorker Annulation avec Helper Fonction

 while (backgroundWorker1.IsBusy) 
    { 
     backgroundWorker1.CancelAsync(); 
     autoResetEvent1.WaitOne(BGW_CANCEL_TIMEOUT); 
    } 

Dans une application il y a un certain nombre de backgroundWorkers. Est-il valide d'utiliser une fonction d'assistance pour annuler backgroundWorkers, comme ça?

CancelBackgroundWorker(BackgroundWorker bgw, AutoResetEvent are) 
{ 
    while (bgw.IsBusy) 
    { 
     bgw.CancelAsync(); 
     are.WaitOne(BGW_CANCEL_TIMEOUT); 
    } 
} 

Ma préoccupation est qu'au lieu de passer les objets en question dans la fonction, les copies sont faites, battant ainsi le but d'avoir la fonction. L'objectif principal de cette fonction est de réduire l'espace de code et de rendre le code d'application plus lisible/maintenable.

Répondre

2

Non, ce n'est pas correct. Il provoque un blocage lorsque le BGW a un gestionnaire d'événement RunWorkerCompleted. Ce gestionnaire ne peut pas s'exécuter tant que le thread principal ne reste pas inactif et rentre dans la boucle de message. La propriété IsBusy restera True jusqu'à ce que ce gestionnaire d'événements se termine.

Vous avez un délai d'attente sur l'appel WaitOne afin qu'au moins votre programme ne se bloque pas complètement. Mais lorsque WaitOne() revient, le BGW est et non, mais le gestionnaire d'événements RWC n'est pas encore exécuté. La seule alternative pratique consiste pour le gestionnaire d'événements RWC à faire tout ce qui est nécessaire lorsque l'annulation est terminée.

+0

C'était tout! Merci! –

0

Votre code est erroné. L'appel CancelAsync appelle simplement CancellationPending flag sur le BackgroundWorker à true. Votre code dans l'événement DowWork devrait vérifier périodiquement ce drapeau et arrêter si le drapeau est true.

Appeler CancelAsync plusieurs fois ne fera pas de bien, et il ne devrait y avoir aucune raison de geler le fil de l'interface utilisateur jusqu'à ce qu'il s'annule réellement.

+0

Oui, je le sais. Mon backgroundWorker a des chèques pour rechercher backgroundWorker1.CancellationPending et quitter en conséquence. Ma question est plutôt de savoir si les flags backgroundWorker1 vont être définis par la fonction helper ou vont définir les flags d'une copie de backgroundWorker, qui est détruit quand la fonction retourne. –

+0

Puisque la classe 'BackgroundWorker' n'est pas une structure, non. Toutes les classes C# sont toujours transmises par référence. Cependant, la fonction est inutile. – SLaks

+0

Les classes sont transmises par valeur, sauf si le mot-clé ref ou out est utilisé. Pour les types de référence, une copie de la référence est transmise. –