appel de méthode asynchrone sans attendre #2
J'ai une méthode asynchrone:
public async Task<bool> ValidateRequestAsync(string userName, string password)
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(url);
string stringResponse = await response.Content.ReadAsStringAsync();
return bool.Parse(stringResponse);
}
}
J'appelle cette méthode comme ceci:
bool isValid = await ValidateRequestAsync("user1", "pass1");
Puis-je appeler la même méthode à partir d'une méthode synchrone, sans l'aide de await
mot-clé?
Ex:
public bool ValidateRequest(string userName, string password)
{
return ValidateRequestAsync(userName, password).Result;
}
Je pense que cela va provoquer un blocage.
MODIFIER
L'appel de la méthode, comme ci-dessus fait l'appel jamais de fin. (La méthode n'a pas atteint la fin)
- Je crois que l'appel d'une méthode asynchrone sans attendre simplement entraînera la méthode à appeler de façon synchrone, le comportement dépend de ce que votre méthode ne fait.
- Je l'ai essayé! Il ressemble à l'appel de la méthode ne se termine jamais
- la méthode est toujours appelée de manière synchrone. Elle retourne une tâche, c'est la seule différence. La magie est dans l'attendent, pas à l'appel.
- Ah je vois, je n'ai pas réellement utilisé async encore; j'ai besoin d'aller en lire plus sur la mécanique. Merci.
- Il est possible que votre méthode de blocage, mais c'est un résultat logique de ne pas partir du fait que vous êtes en l'appelant en mode synchrone.
- Si vous exécutez ce code sur un seul thread contexte d'exécution, tel qu'un thread d'INTERFACE utilisateur, il sera très certainement l'impasse, parce que le thread est en attente pour le fil de devenir disponibles. Si vous l'exécutez sur un pool de threads thread, vous êtes fine.
- J'ai édité ton titre. Se reporter à la rubrique "si vous avez des questions comprennent “tags” dans leurs titres?", où le consensus est "non, ils ne devraient pas".
- Je vais faire la prochaine fois, merci
Vous devez vous connecter pour publier un commentaire.
Si vous appelez une méthode asynchrone à partir d'un seul thread contexte d'exécution, tel qu'un thread d'INTERFACE utilisateur, et d'attendre le résultat de façon synchrone, il y a une forte probabilité de blocage. Dans votre exemple, que la probabilité est de 100%
Penser. Ce qui se passe lorsque vous appelez
Vous appelez la méthode ValidateRequestAsync. Là vous appeler ReadAsStringAsync. Le résultat est qu'une tâche devra être retourné à la thread de l'INTERFACE utilisateur, avec une poursuite prévue à poursuivre l'exécution sur le thread d'INTERFACE utilisateur lorsqu'il devient disponible. Mais bien sûr, il ne sera jamais disponible, car il est en attente (bloqué) pour la fin de la tâche. Mais la tâche ne peut pas terminer, car il est en attente pour le thread d'INTERFACE utilisateur de devenir disponibles. L'impasse.
Il existe des moyens pour éviter ce blocage, mais ils sont tous d'une Mauvaise Idée. Juste par souci d'exhaustivité, on peut travailler:
C'est une mauvaise idée, parce que vous avez encore de bloquer votre thread de l'INTERFACE utilisateur d'attente et de ne rien faire d'utile.
Alors, quelle est la solution alors? Aller async tout le chemin. L'appelant d'origine sur le thread d'INTERFACE utilisateur est probablement un gestionnaire d'événement, alors assurez-vous que est asynchrone.
.ConfigureAwait
pourrait vous aider. Mais attention: l'action des filtres doivent s'exécuter rapidement. À l'aide de.Result
va bloquer un thread, et c'est quelque chose qui doit être évité, aussi dans l'action des filtres.task.ConfigureAwait(false).Result
ne sera certainement pas de travail. Il n'a même pas de compiler, depuisConfigureAwait()
ne retourne pas uneTask
.UserManager
dans ASP.NET a seulement uneGetUserAsync
méthode. Je pense qu'il est parfaitement possible d'utiliser de laTask.Run
construire pour bloquer le thread, si vous êtes à la construction d'une API RESTful qui n'a pas de thread d'INTERFACE utilisateur dans tous les cas, en particulier parce que les asp.net l'API web ne semble pas être conçu pour async méthodes de saisie, ce qui n'aurait aucun sens, en tout cas.vous pouvez utiliser le retour ValidateRequestAsync(nom d'utilisateur, mot de passe).GetAwaiter().GetResult();