Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Programmation asynchrone : warnings à connaître…

[new:15/11/2012]La programmation asynchrone était déjà entrée depuis longtemps dans la panoplie du développeur, même si certains sont arrivés à faire l’autruche jusqu’à maintenant. Mais avec Windows 8 l’asynchrone est une obligation. Certains warnings du compilateurs matérialisent des erreurs fréquentes. Regardons les deux plus fréquents…

Code CS1998

Rien à voir avec l’année 98. Cela laisse juste présager qu’il y a1997 autres erreurs possibles et ça donne le vertige (mais la prochaine fera encore plus peur !).

Le code CS1998 affiche le message suivant (je travaille avec des versions US, je ne connais pas la traduction exacte en français) :

warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

La cause est assez simple : vous avez spécifié le modificateur “async” dans l’entête de la méthode mais vous ne faites aucun usage de “await” dans cette dernière.

C’est un avertissement à prendre au sérieux. Soit vous avez placé cet “async” pour rien, et il faut le retirer… soit vous aviez prévu d’utiliser “await” et vous avez oublié de le faire ce qui risque de fausser “légèrement” le fonctionnement de la méthode. Situation à corriger immédiatement donc.

Code CS4014

Le vertige devient digne de celui d’un Baumgartner avant de sauter… imaginez 4012(*) autres warnings à découvrir ! :-)

(*) les plus futés auront noté l’erreur… j’aurai du dire 4013 n’est-ce pas ? Ceux qui suivent vraiment auront compris qu’il n’y a pas d’erreur, puisque je vous ai déjà fait découvrir la 1998, il en reste bien 4012 à connaître !

Le message de celui-ci est tout aussi important à reconnaître :

warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

La cause : Vous appelez une méthode qui possède le modificateur “async” et qui retourne une Task<> et votre code ne fait rien pour attendre le résultat de cette dernière.

Peut-être est-ce volontaire. Le cas peut se produire (si le code qui suit l’appel ne se sert pas du résultat par exemple).

Si ce n’est pas intentionnel il est urgent de vérifier de le code appelant et le code appelé !

Si la situation est voulue, on peut supprimer le warning avec un #pragma. Cela est tout à fait acceptable car l’intention du développeur devient visible : il assume la situation. C’est mille fois préférable à un warning laissé en l’état.

Une autre astuce consiste à tout simplement déclarer un variable qui ne sert à rien et lui affecter le résultat de l’appel, de type “var dummy = appelDeCodeAsync;”

Ne vous inquiétez pas pour cette variable supplémentaire, le compilateur est assez malin pour la supprimer totalement du code compilé. Son avantage est d’éviter un #pragma (qui exige de spécifier deux fois le code du warning avec possibilité de se tromper). Comme cette solution ne coûte rien dans le code compilé elle est intéressante. Bien entendu elle sous-entend une parfaite compréhension du warning en question et ne doit pas servir à masquer une situation non maîtrisée !

Je préfère le #pragma qui marque l’intention plus clairement. Mais le risque de supprimer le warning dans tout le code (en cas d’erreur sur le second code) et de masquer des erreurs potentielles me chagrine tout autant.

A vous de voir…

Conclusion

La programmation asynchrone est pleine de surprise. Certains développeurs laissent parfois des tartines de warnings dans leurs projets. Pourtant il faut les traiter avec la même vigilance que des erreurs de compilation car derrière chaque warning peut se cacher de potentiels bugs très sournois.

Le cas des warnings 1998 et 4014 est intéressant à ce titre.

Les warnings sont des erreurs comme les autres, mais de nature plus vicieuse, c’est un peu la leçon à retenir de ce billet…

Stay Tuned !

blog comments powered by Disqus