Question

Dites que je montre à l'utilisateur un formulaire et que j'utilise un BackgroundWorker pour effectuer certains travaux en arrière-plan.

Lorsque l'utilisateur clique sur OK, je ne peux pas continuer tant que BackgroundWorker n'est pas terminé. S'il n'a pas terminé lorsque l'utilisateur clique sur OK, je souhaite afficher un WaitCursor jusqu'à ce qu'il le soit, puis continuer.

Quel est le meilleur moyen de mettre en œuvre cela?

Je sais que je pourrais utiliser un vieux thread ordinaire, puis le faire.Join, mais j'aime bien BackgroundWorker.

Peut-on le faire gentiment?

Était-ce utile?

La solution

Vous pouvez utiliser ce code au lieu de BW

var resetEvent = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(state =>
                {
                    Thread.Sleep(5000);//LongRunning task, async call
                    resetEvent.Set();
                });
resetEvent.WaitOne();// blocking call, when user clicks OK 

Autres conseils

Idéalement, vous devez désactiver tous les contrôles pertinents du formulaire, puis les réactiver à la fin du BackgroundWorker . De cette façon, vous ne obtiendrez pas une interface utilisateur verrouillée - et vous pouvez avoir un bouton Annuler, etc.

Si vous souhaitez bloquer réellement jusqu'à la fin, vous pouvez exécuter la tâche de manière synchrone pour commencer.

Vous pouvez vérifier si BackgroundWorker est en cours d'exécution avec une vérification dans le gestionnaire d'événements btnOK_Click pour voir si bw.IsBusy est à true. Si tel est le cas, modifiez le curseur et définissez un indicateur booléen indiquant que le gestionnaire OK est en attente. Lorsque BackgroundWorker a terminé son travail, vérifiez si ok est en attente. Si tel est le cas, définissez le drapeau sur False, changez le curseur et exécutez le travail en cliquant sur le bouton OK. : -)

Je n'utiliserais que des drapeaux booléens et un cadenas.

object waitlock = new object();
bool isBackgroundWorkerCompleted = false;
bool isOKButtonPressed = false;

private void onPress(...) 
{
    lock(waitlock) 
    {
      isOKButtonPressed = true;
      if (isBackgroundWorkerCompleted) DoNextStep();
      else cursor.Wait(); //psuedo-code - use whatever the actual call is...
    }
}

Le fil d’arrière-plan fait la même chose (n'oubliez pas de commencer à invoquer à nouveau le fil principal de l'interface utilisateur)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top