2016-12-22 4 views
3

J'ai ce codecomment faire pour exécuter les appels asynchrones de façon synchrone dans C#

ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password) 

Je veux que ce morceau de code à exécuter Synchrone, parce que ma déclaration suivante est très dépendent de cela. L'appel ci-dessous échoue la plupart du temps car l'utilisateur est nul.

var roles = await userManager.GetRolesAsync(user.Id); 

Une suggestion?

+0

Que diriez-vous de vérifier '' 'si {/ * faire vos affaires * /} '' '' ''? – tym32167

+3

Assez sûr que cela n'a rien à voir avec être asynchrone, le mot-clé 'await' devrait prendre soin de mettre en pause l'exécution. Êtes-vous sûr que l'appel pour que ApplicationUser réussisse? On dirait que ça retourne null. – Equalsk

+5

Vous n'avez rien à faire - la ligne suivante sera exécutée ** UNIQUEMENT ** après la fin de la recherche de FindAsync. si 'roles' n'est pas ce que vous attendez, vérifiez les problèmes de codage ou de données, pas de problèmes avec async –

Répondre

2
ApplicationUser user = userManager.FindAsync(context.UserName, context.Password).Result; 
var roles = userManager.GetRolesAsync(user.Id).Result; 

Mais si l'utilisateur contexte est tout simplement nul, il ne vous aidera pas si vous le faites de manière synchrone - l'utilisateur sera aussi NULL comme avant.

Si vous essayez d'ajouter un nom de connexion à votre demande, il peut être utile de vérifier this.
En outre, vous devriez probablement utiliser policies au lieu de rôles.

Edit:
OK, sans interblocage problème que je ne connaissais pas (@hvd merci): Si la méthode async retourne void

Task.Run(() => asyncMethod()).Wait(); 
+0

Ce n'est pas nécessaire. Le code original n'a aucun problème –

+0

@Panagiotis Kanavos: Je sais, mais c'est la réponse à sa question. –

+2

@StefanSteiger Le problème est [un problème XY] (https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Le problème * real * est 'user' étant' null', pas le code qui s'exécute de manière asynchrone. Votre réponse devrait échouer pour le vrai problème exactement de la même manière que le propre code de l'OP, et en plus, vous avez introduit la possibilité de blocage en fonction de l'endroit où ce code est appelé et comment 'FindAsync' est implémenté. – hvd

0

Je ne

var user = Task.Run(() => userManager.FindAsync(context.UserName, context.Password)).Result; 
var roles = Task.Run(() => userManager.GetRolesAsync(user.Id)).Result; 

voir pourquoi il pourrait y avoir un problème - si vous await correctement, user devrait être recherché correctement avant GetRolesAsync appel. Est-ce votre code entier?

Mayby, user est null parce qu'elle n'existe pas?

En outre, vous pouvez enchaîner vos appels au lieu de l'exécuter de manière synchrone:

var roles = await userManager.FindAsync(context.UserName, context.Password) 
          .ContinueWith(task => 
               userManager.GetRolesAsync(task.Result.Id)) 
          .Unwrap(); 
+0

Le chaînage ne changera rien. L'effet sera le même que 'await'. Si le résultat est null, la méthode chaînée échouera –

3

Il n'y a rien de mal avec le code. await signifie que l'exécution continue seulement après la méthode asynchrone qui suit se termine. Cela signifie que dans cet extrait:

var user = await userManager.FindAsync(context.UserName, context.Password) 
var roles = await userManager.GetRolesAsync(user.Id); 

l'appel à GetRolesAsync ne sera exécutée que après la ligne précédente est terminée.

D'après la documentation de UserManager.FindAsync

Renvoie un utilisateur avec le nom d'utilisateur spécifié et mot de passe ou null s'il n'y a pas de correspondance.

Le nom d'utilisateur ou le mot de passe est erroné. Renvoyez juste un message à l'utilisateur final lui demandant de réessayer. Si vous passez cet appel en utilisant des informations d'identification stockées, vérifiez-les à nouveau.

Dans tous les cas, vous devez vérifier un échec d'authentification avant d'essayer d'utiliser la valeur user, par exemple: (! User = null)

var user = await userManager.FindAsync(context.UserName, context.Password) 
if (user == null) 
{ 
    //Somehow report failure, decrement retry counters, etc 
    retries--; 
    return false; 
} 
else 
{ 
    var roles = await userManager.GetRolesAsync(user.Id); 
    .... 
}