Question

Existe-t-il un moyen de "redémarrer" directement un travailleur de fond? L'appel de CancelAsync () suivi de RunWorkerAsync () ne le fera manifestement pas comme leur nom l'indique.

Informations générales: J'ai un travailleur d'arrière-plan qui calcule un total dans mon application Windows Forms .net 2.0. À chaque fois que l'utilisateur modifie une valeur faisant partie de ce total, je souhaite redémarrer le travailleur d'arrière-plan au cas où il serait en cours d'exécution afin que les dernières valeurs soient prises en compte.

Était-ce utile?

La solution

Le travail de fond ne fait pas d’annulation.

Lorsque vous appelez bgw.CancelAsync , un indicateur de l'agent de fond que vous devez vérifier vous-même dans le gestionnaire DoWork.

quelque chose comme:

bool _restart = false;

private void button1_Click(object sender, EventArgs e)
{
    bgw.CancelAsync();
    _restart = true;
}

private void bgw_DoWork(object sender, DoWorkEventArgs e)
{

    for (int i = 0; i < 300; i++)
    {
        if (bgw.CancellationPending)
        {
            break;
        }
        //time consuming calculation
    }
}

private void bgw_WorkComplete(object sender, eventargs e)  //no ide to hand not sure on name/args
{
    if (_restart)
    {
        bgw.RunWorkerAsync();
        _restart = false;
    }

}

Autres conseils

Il y a plusieurs options, tout dépend de la façon dont vous voulez écorcher ce chat:

Si vous souhaitez continuer à utiliser BackgroundWorker , vous devez respecter le modèle qui a été défini, à savoir l'un des "facteurs de sensibilité au progrès". Les éléments contenus dans DoWork sont clairement tenus de toujours savoir si une annulation en attente est due (c’est-à-dire qu’une certaine interrogation doit avoir lieu dans votre DoWork boucle).

Si votre code de calcul est monolithique et que vous ne voulez pas le gêner, n'utilisez pas BackgroundWorker , mais lancez votre propre thread - vous pourrez ainsi le tuer avec force si besoin est.

Vous pouvez connecter le gestionnaire d'événements change pour les contrôles dans lesquels les valeurs sont modifiées et effectuer les opérations suivantes dans le gestionnaire:

if(!bgWrkr.IsBusy)
     //start worker
else if(!bgWrkr.CancellationPending)
  bgWrkr.CancelAsync();

J'espère que cela vous aide!

Je souhaite laisser mes requêtes en cours d'exécution, mais je ne me soucie plus des résultats. Je remplace la valeur du travailleur d’arrière-plan (mon compteur occupé utilise le drapeau isBusy).

    private void SearchWorkerCreate() {
        this.searchWorker = new BackgroundWorker();
        this.searchWorker.DoWork += this.SearchWorkerWork;
        this.searchWorker.RunWorkerCompleted += this.SearchWorkerFinish;
    }

    private void SearchWorkerStart(string criteria){
        if(this.searchWorker.IsBusy){
            this.SearchWorkerCreate();
        }
        this.searchWorker.RunWorkerAsync(criteria);
        this.OnPropertyChanged(() => this.IsBusy);
        this.OnPropertyChanged(() => this.IsIdle);
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top