comment oublier le contexte de synchronisation dans les méthodes asynchrones en c #

Supposons que je veuille écrire une méthode asynchrone M. Je ne sais pas quel type de contexte de synchronisation sera utilisé (interface utilisateur, ASP.NET, application console, etc.) pour l’appeler. J’aimerais que la méthode soit aussi facile à utiliser que possible. Cela signifie que tout le monde devrait pouvoir l’appeler de manière synchrone en accédant au membre Result de la tâche renvoyée.

public async Task M() { // lot's of calling of helper methods including awaits, etc. // helper methods not owned by me // ... return 42; } // this should be safe to do from any synchronization context int result = M().Result; // Synchronously wait 

Le problème est que le contexte de synchronisation de l’appelant de la méthode M est divulgué dans les appels de M. Si l’un d’entre eux souhaite continuer sur le contexte de synchronisation transmis, il peut se bloquer (par exemple, lors de l’utilisation du contexte de synchronisation de l’interface utilisateur).

Une solution pour oublier le contexte de synchronisation lorsque M est appelé consiste à envelopper le contenu de M dans Task.Run. Cependant, cela forcera un saut de fil, y compris dans les cas où toutes les tâches de M sont terminées et que tout peut être exécuté de manière synchrone sur le même fil sans changement de contexte. Existe-t-il une meilleure solution pour oublier le contexte de synchronisation d’un thread? Ou est-ce que je manque quelque chose qui rendrait cette question sans importance?

J’aimerais que la méthode soit aussi facile à utiliser que possible. Cela signifie que tout le monde devrait pouvoir l’appeler de manière synchrone en accédant au membre Result de la tâche renvoyée.

Il n’existe pas de moyen facile de créer un wrapper synchrone pour une méthode asynchrone . Il est préférable de laisser les méthodes asynchrones être asynchrones.

Vous pouvez utiliser ConfigureAwait(continueOnCapturedContext: false) pour ignorer le contexte, mais ce ne sera pas mieux que Task.Run dans votre cas, car vous ne pouvez pas modifier les méthodes que M appelle.