9
votes

Comment gérer des exceptions d'un fil d'antécédents?

Dans une application WPF, j'ai une tâche d'accès à la base de données ShedUlled, exécutée périodiquement par une minuterie et cette tâche a été exécutée dans un thread du travail d'arrière-plan.

Lorsque la tentative de connexion a échoué, je soumette une exception par try_catch Construction et je souhaite mettre à jour un texte de barre d'état dans un fil d'interface utilisateur.

y a-t-il une certaine construction d'événements de Prebuild dans un bourreur d'arrière-plan pour la mise en œuvre de cela, quelque chose comme doworkeventhandler ou RunworkercompletedeDeHandler , qui peut être utilisé pour cela? Sinon, comment le faire mieux?

édité (ajouté):

Si je veux gérer l'exception à l'intérieur RunworkerCompletDeDeHandler , à l'aide du paramètre E.Error , cela ne fonctionne pas. Si je quitte une exception sans ménagère dans le fil d'arrière-parcours , l'application se bloque et des points de débogueur sur la chaîne de code qui est excédée à l'intérieur Backworker WHORDER, en disant que: < EM> L'exception n'a pas été non heurtée par le code de l'utilisateur .

Donc, dans ce cas, le thread n'arrête pas seulement, signalant sur RunworkerCompletdeDeventHandler qu'il s'est arrêté avec erreur, mais l'application entière cessa de fonctionner.


1 commentaires

Merci à tous pour répondre! Prenant en compte certaines réponses, j'ai mis à jour ma question avec plus de détails.


5 Réponses :


6
votes

Le RunworkCompleteDeDeventargs E du RunworkCompletDeDeventHandler Contient une erreur Erreur de type exception. Si aucune exception ne s'est produite lors du travail du fil d'arrière-plan, le PrPERY a NULL comme valeur. Sinon, il contient l'erreur survenue.


0 commentaires

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

1 commentaires

Lorsque j'essaie de jeter une exception à partir du fil du travail d'arrière-plan, l'application se bloque avec: une exception n'a pas été non heurtée par le code de l'utilisateur. Je n'arrive jamais à bw_runworkercompled. Est-ce que je manque quelque chose?



5
votes

Un UI WPF peut être mis à jour à partir d'un fil d'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: P>

StatusDisplay.ShowStatus("Connection Failed!");


2 commentaires

Dans mon cas, le code d'arrière-plan ne fait pas partie d'une fenêtre, mais elle circule dans une classe distincte. De plus, une exception a lieu dans une méthode statique. Donc, ce mot clé n'est pas valable dans ce cas. S'il vous plaît, aidez-moi à comprendre comment je pourrais faire référence à ma fenêtre principale de l'interface utilisateur dans ce cas?


J'ai ajouté des notes en réponse à votre question.



3
votes

Définissez la propriété WORKERERREPORTSPROGRESSPORTSPROGRESSE FORT> de l'ouvrier de l'arrière-plan sur True Strard>, puis ajoutez un gestionnaire d'événements pour l'événement ProgressChanged strong>. Dans le code suivant, j'ai ajouté un gestionnaire d'événements pour form.load également.

Essayez maintenant le code suivant: P>

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            MessageBox.Show(e.UserState.ToString());
        }

        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();
        }


0 commentaires

0
votes

Si je veux gérer l'exception à l'intérieur RunworkComplettedeventHandler code>, à l'aide de E.Error code> paramètre, il ne fonctionne pas. Au cas où je quitterais une exception non heurtée dans le Backworker Code> Le fil, l'application se bloque et des points de débogueur à la chaîne de code excluée à l'intérieur wworker code> thread, Dire que: l'exception n'a été non géré par le code de l'utilisateur em> strong>. p>

Donc, dans ce cas, le fil ne vous arrête pas, signalant à RunworkPompletDeDeHandler code> qu'il s'est arrêté avec une erreur, mais le Toute application Arrête de fonctionner. P>

Je suis très curieux de cela. Essayez d'exécuter le code suivant dans une application de console et voyez si votre programme se bloque ou si l'erreur apparaît dans le RunworkCompleteDeDeventargs code>. P>

    static void Main(string[] 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();
    }


0 commentaires