Comment gérer les exceptions d’un thread BackgroundWorker?

Dans une application WPF, j’ai une tâche d’access à la firebase database planifiée, exécutée périodiquement par un minuteur et cette tâche a été exécutée dans un thread BackgroundWorker.

Lorsque la tentative de connexion a échoué, je try_catch une exception à l’ try_catch construction try_catch et je souhaite mettre à jour un texte de barre d’état dans un thread d’interface utilisateur.

Existe-t-il une construction d’événement de pré-construction dans BackgroundWorker pour l’implémenter, quelque chose comme DoWorkEventHandler ou RunWorkerCompletedEventHandler , qui peut être utilisée pour cela? Si non, comment mieux le faire?

Edité (ajouté):

Si je veux gérer l’exception à l’intérieur de RunWorkerCompletedEventHandler , en utilisant le paramètre e.Error , cela ne fonctionne pas. Si je laisse une exception non gérée dans le thread BackgroundWorker , l’application est suspendue et le débogueur pointe vers la chaîne de code qui est exécutée dans le thread BackgroundWorker , en indiquant que: Exception n’a pas été gérée par le code utilisateur .

Ainsi, dans ce cas, le thread ne s’arrête pas, signalant à RunWorkerCompletedEventHandler qu’il s’est arrêté avec une erreur, mais que l’application entière ne fonctionne plus.

Une interface utilisateur WPF peut être mise à jour à partir d’un thread en arrière-plan à l’aide de Dispatcher.BeginInvoke.

Par exemple, si votre code d’arrière-plan faisait partie d’une fenêtre, vous pouvez mettre à jour un TextBlock:

 this.Dispatcher.BeginInvoke((Action)(() => { textBlock.Text = "Connection Failed!"; })); 

Modifier:

Si votre code d’arrière-plan était dans une classe autre que votre fenêtre, vous pouvez créer une interface pour vous aider:

 public interface IShowStatus { void ShowStatus(ssortingng message); } 

Implémenter l’interface dans votre fenêtre

 public void ShowStatus(ssortingng message) { this.Dispatcher.BeginInvoke((Action)(() => { textBlock.Text = message; })); } 

Dans votre classe avec l’agent d’arrière-plan, créez une propriété pour contenir une référence à l’interface.

 public IShowStatus StatusDisplay { get; set; } 

Dans votre classe Window, initialisez la classe d’arrière-plan.

 public void InitBackground() { BackgroundClass background = new BackgroundClass(); background.StatusDisplay = this; ... 

Enfin, dans votre fil de discussion, vous pouvez dire:

 StatusDisplay.ShowStatus("Connection Failed!"); 

La RunWorkerCompletedEventArgs e de RunWorkerCompletedEventHandler contient la propriété Error celle-ci est de type Exception. Si aucune exception ne s’est produite pendant le travail du thread d’arrière-plan, le prpery a la valeur null. Sinon, il contient l’erreur qui s’est produite.

 private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Exception exceptionThrowDuringDoWorkEventHandler = e.Error; } 

Définissez la propriété WorkerReportsProgress du travailleur d’arrière-plan sur true , puis ajoutez un gestionnaire d’événements pour l’événement ProgressChanged . Dans le code suivant, j’ai également ajouté un gestionnaire d’événements pour Form.Load.

Maintenant, essayez le code suivant:

 private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { MessageBox.Show(e.UserState.ToSsortingng()); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { try { //some code that throws an exception throw new NotImplementedException(); } catch (Exception ex) { backgroundWorker1.ReportProgress(0/*percent of progress*/, ex); } } private void Form1_Load(object sender, EventArgs e) { backgroundWorker1.RunWorkerAsync(); } 

Si je veux gérer l’exception à l’intérieur de RunWorkerCompletedEventHandler , en utilisant le paramètre e.Error , cela ne fonctionne pas. Si je laisse une exception non gérée dans le thread BackgroundWorker , l’application est suspendue et le débogueur pointe vers la chaîne de code qui est exécutée dans le thread BackgroundWorker , en indiquant que: Exception n’a pas été gérée par le code utilisateur .

Ainsi, dans ce cas, le thread ne s’arrête pas, signalant à RunWorkerCompletedEventHandler qu’il s’est arrêté avec une erreur, mais que l’application entière ne fonctionne plus.

Je suis très curieux à ce sujet. Essayez d’exécuter le code suivant dans une application de console et voyez si votre programme se bloque ou si l’erreur s’affiche dans le RunWorkerCompletedEventArgs .

  static void Main(ssortingng[] args) { var bw = new BackgroundWorker(); bw.DoWork += Bw_DoWork; bw.RunWorkerCompleted += Bw_RunWorkerCompleted; bw.RunWorkerAsync(); Console.ReadKey(); } private static void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Console.WriteLine("Complete."); Console.WriteLine(e.Error); } private static void Bw_DoWork(object sender, DoWorkEventArgs e) { throw new NotImplementedException(); }