0
votes

C # - Dispatcher.invokeasync continue avec non attendu

supposer graphviewmodels est un Observablecollection , le code suivant fonctionne comme prévu: xxx

au lieu de l'enveloppe Le updateChartSwithValuesasync Methode appelle dans le Continuwith Délégué, la méthode n'est plus attendue. J'ai déjà essayé de changer le configureawait (false) sur vrai mais rien ne semble changer. Au-dessous du code édité: xxx

le code dans le répartiteur est toujours exécuté avant que le reste continue avec délégué 't attendre updatechartwithvaluesasync pour compléter plus, levant des bugs méchants.

Peut-on expliquer ce comportement? Merci

WPF, .NET Framework 4.7 Projet


1 commentaires

Je ne suis pas expert, mais je pense que UpdatechartThithValuesasync est en fait attendu, mais sur un autre fil. Essayez de ne pas mélanger ASYNC / Attendre avec des outils surtout utiles avant que ASYNC / AWAIT n'existait (comme Continuwith ... Je ne sais pas pourquoi vous voudriez l'utiliser ici).


3 Réponses :


1
votes

Dispatcher.Invokeasync renvoie un DispatcherOveration . Ceci est un type attendable, car il implémente une méthode appelée getawaiter () qui renvoie un type qui implique inotifycompletion .

Lorsque vous utilisez attendre sur le résultat de Dispatcher.invokeasync directement, l'achèvement de DispatcherOperSeration est attendu avant l'appel sur updateChartSwithvaluesasync .

. Dans votre deuxième exemple, vous n'attendez pas cela directement; Vous attendez le résultat de l'expression chaînée: xxx

alors que seul l'objet final ( tâche ) est attendu, ce qui signifie que la fonction que vous passez à < Code> Continuwith peut être exécuté, avant Dispatcher.invokeasync est terminé.

Si vous utilisez async / attendre, il serait prudent de < / Strong> Utilisez les mots-clés d'une méthode asynchrone, car le mélange avec les opérations basées sur le rappel conduit à un code déroutant tel que celui-ci.


0 commentaires

1
votes

Comme autre réponse mentionnée, vous ne devriez pas mettre async t => attendre updateCharetswithvitvaluesasync dans votre Continuwith rappel, car il aurait en attente de la tâche > Continuwith (...) Méthode, qui finirait éventuellement à finir immédiatement.

Si vous voulez vraiment attendre pour continuer à finir dans la plupart des attendre , vous devriez Débit ( ) Votre Tâche et attendez-vous ou utilisez l'API synchrone à l'intérieur, mais rappelez-vous de la bonne gestion du contexte de synchronisation. xxx

Notez que attendre est traduit en bloc de code impliquant Continuwith qui fonctionnalités ConfigureAWAIT Options et plus, donc vous feriez mieux d'utiliser async attendre constructions comme si vous avez essayé dans votre premier exemple.


0 commentaires

1
votes

Mettez simplement, .Continuewith () ne fait pas attendre dans sa mise en œuvre, il exécute plutôt la transmission du délégué tel qu'il est et renvoie une tâche de tâche ( Tâche > ). Cette tâche extérieure, car ne pas attendre sur la déléguée transmise, se termine immédiatement.

Ce que je suggère, n'utilisez pas .Continuewith () Dans ce cas, il suffit de vous attendre. Si vous souhaitez vraiment conserver le code actuel, vous pouvez faire .Continuewith (). Doulez () , qu'est-ce qui fera le tour?

Voici une autre question connexe dans le sujet: Utilisez un rappel ASYNC avec la tâche.Continuewith

Si vous voulez en savoir plus en profondeur, le code source de continue avec : https://referencesource.microsoft.com/#msmscorlib/system/threading/tasks/task.cs 4532


1 commentaires

Bonne réponse. Une alternative à Le débouché est en attente de deux fois: attendre