0
votes

Une exception du type 'system.threading.tasks.taskcanceledexception' s'est produite mais n'a pas été traitée dans le code de l'utilisateur

Je reçois cette erreur lorsque vous essayez d'annuler et de redémarrer une tâche code> en utilisant Ceci comme guide. Ce n'est pas clair pour moi, c'est pourquoi l'erreur se produit malgré un essai / attrape.

Que devrait-il arriver strud> p>

Le code est conçu pour exécuter une tâche de recherche après un utilisateur Entre une valeur dans la zone de texte à la suite d'un délai de 1 seconde. Toutefois, si l'utilisateur continue de taper après le délai, j'aimerais annuler la tâche et le redémarrer. P>

code dans la fenêtre principale (PSMEarch) pour démarrer la tâche forte> p>

tirant la tâche fonctionne. Voici le code: P>

private async Task SearchAsync()
{
    CancellationSource = new CancellationTokenSource();
    try
    {
        System.Diagnostics.Debug.WriteLine("Starting Task");
        await Task.Run(() =>
        {
            decimal result = 0;
            // Loop for a defined number of iterations
            for (int i = 0; i < 100; i++)
            {
                // Check if a cancellation is requested, if yes,
                // throw a TaskCanceledException.
                CancellationSource.Token.ThrowIfCancellationRequested();

                // Do something that takes times like a Thread.Sleep in .NET Core 2.
                Thread.Sleep(10);
                result += i;
            }

            System.Diagnostics.Debug.WriteLine("Result: " + result.ToString());
        });
    }
    catch (OperationCanceledException)
    {
        System.Diagnostics.Debug.WriteLine("Op cancelled exception.");
    }
}

private void CancelSearch(object sender, EventArgs e)
{
    System.Diagnostics.Debug.WriteLine("Cancel Search");
    CancellationSource?.Cancel();
}


0 commentaires

3 Réponses :


0
votes

MISE À JOUR

NOTE STROND>: La question a été mise à jour de manière significative car cela a été répondu em>. SUB> P>

quand Éliminer une tâche em>, il existe une différence subtile dans la façon dont exceptions em> sont manipulées. p>

Voir le blog de Stephen Cleary sur ASYNC et attendre . SUB> P>

La meilleure approche serait de simplement faire tout ce async code>. Cela permettra à l'exception em> être placée sur la tâche em> et à être à son tour être jeté em> et être attrapé em> où Vous vous attendez à ce que ce soit p> xxx pré>

Toutefois, en fonction de votre charge de travail (et s'il s'agit d'une CPU liée), cela devrait probablement simplement être un Sync code> et le Tâche CODE> Exécuter lorsque vous appelez la méthode em>. p>

Voir le blog de Stephen Cleary sur Tâche.Run Etiquette Exemples: N'utilisez pas de tâche.Run dans la mise en œuvre SUB> P >

une autre solution (moins éloquente), consiste à capturer l'exception em> et à le placer sur la tâche em>, cela jettera la exception em> quand La méthode est attendue em>, et suit de plus de près ce que le compilateur généré iaisyncstatemachine code> implémentera lors de l'utilisation du async et de l'attente modèle em> p>

task = Task.Run(() =>


3 commentaires

À partir de l'article que j'ai raconté, l'essai / attrape est en dehors de la tâche.Run. Notez que j'utilise Await aussi: var résultats = AwaitearchTask où SearchTâche est défini sur la fonction exécutant la tâche ( SearchPDFasync )


Intéressant. Appliquer votre première suggestion dans mon édition ci-dessus, cela semble fonctionner. La seule chose à noter est que pour attendre la tâche.delay, je devais faire la fonction anoynmous dans laquelle exécuter async: attendre la tâche.run (_ASYNC_ () => ... ...


Cela peut être éloigné d'ASYNC / attendre entièrement à la suite de votre autre recommandation. Je ne sais pas comment cette implémentation fonctionnerait encore, étant donné que je voudrais créer une barre de recherche dynamique qui redémarre en tant qu'utilisateurs entrant de nouveaux termes. Appréciez l'aide de toute façon.



0
votes

Essayez d'utiliser CANCellationToken.ththrowifcancolellationRequée (); ÉDITER: Désolé, essayez de le faire sans utiliser la tâche.Run (); xxx

attendre la tâche.yield (); retournera le contrôle de la méthode et de la file d'attente à l'exécution ultérieure. Pourrait fonctionner


3 commentaires

Je pense ça marche. Maintenant, il suffit de verrouiller mon UI ... Devrait avoir à voir avec Seversethermingred n'étant pas asynchronisé.


De ce point, je suppose que vous pouvez simplement faire une tâche d'attente.yield (); à nouveau mais au début de SearchAssync ();


Cela fera la même chose. Il retournera le contrôle de la méthode de synchronisation. Et après continuer à exécuter la tâche



0
votes

La réponse de Michael Randall, j'ai été forcée de tout attendre. C'est moche, mais ça marche.

Les changements de clé:

  • SearchErmentasered est maintenant un gestionnaire asynchronisé
  • SearchAssync () est appelé avec attendre
  • Tâche.Run est appelé avec l'attente et sa fonction anonyme appelée avec async XXX


0 commentaires