L'appel de méthode asynchrone sur le bouton cliquez sur
J'ai créé Windows Phone 8.1 projet et je suis en train de lancer asynchrone de la méthode GetResponse(string url) sur le bouton cliquez sur et en attente de la méthode à la fin, mais la méthode est de ne jamais se terminer. Voici mon code:
private void Button_Click(object sender, RoutedEventArgs
{
Task<List<MyObject>> task = GetResponse<MyObject>("my url");
task.Wait();
var items = task.Result; //break point here
}
public static async Task<List<T>> GetResponse<T>(string url)
{
List<T> items = null;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
var response = (HttpWebResponse)await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
try
{
Stream stream = response.GetResponseStream();
StreamReader strReader = new StreamReader(stream);
string text = strReader.ReadToEnd();
items = JsonConvert.DeserializeObject<List<T>>(text);
}
catch (WebException)
{
throw;
}
return items;
}
Il va s'accrocher sur la tâche.Wait().
J'ai changé mon bouton cliquez sur la méthode async et utilisé attendre avant que la méthode asynchrone et j'obtiens le résultat(await GetResponse<string>("url")
). Quel est le problème avec Task<List<string>> task = GetResponse<string>("url")
?
Ce que je fais mal?
Merci pour l'aide!
- Juste une petite remarque, c'est une convention générale qui
async
méthodes sont suffixé avecAsync
, par exemple, votre nom de méthode seraitGetResponseAsync
.
Vous devez vous connecter pour publier un commentaire.
Vous êtes la victime de la classique de blocage.
task.Wait()
outask.Result
est un appel bloquant dans le thread de l'INTERFACE utilisateur qui provoque le blocage.Ne pas bloquer le thread d'INTERFACE utilisateur. Ne jamais le faire. Juste l'attendent.
Btw, pourquoi êtes-vous de les attraper, les
WebException
et de le jeter en arrière? Il serait préférable si vous simplement ne pas l'attraper. Les deux sont les mêmes.Aussi, je peux voir que vous êtes en mélangeant le code asynchrone synchrone code à l'intérieur de la
GetResponse
méthode.StreamReader.ReadToEnd
est un appel bloquant --vous devriez être en utilisantStreamReader.ReadToEndAsync
.Également utiliser "Async" suffixe à des méthodes qui retourne une Tâche ou asynchrone à suivre le ROBINET("Tâche en fonction du Modèle Asynchrone") de la convention comme Jon dit.
Votre méthode devrait ressembler à quelque chose comme ce qui suit lorsque vous avez résolu tous les problèmes ci-dessus.
C'est ce qui vous tue:
Qui bloque le thread d'INTERFACE utilisateur jusqu'à ce que la tâche soit terminée (mais la tâche est une méthode asynchrone qui va essayer de revenir au thread d'INTERFACE utilisateur après la "pause" et s'attend à une async résultat. Il ne peut pas le faire, parce que vous êtes bloquer le thread d'INTERFACE utilisateur...
Il n'y a rien dans votre code qui ressemble vraiment, il faut que le thread d'INTERFACE utilisateur de toute façon, mais en supposant que vous avez vraiment ne le voulez pas, vous devez utiliser:
Ou tout simplement:
Maintenant, au lieu de blocage jusqu'à ce que la tâche est terminée, le
Button_Click
méthode sera de retour après la planification d'une poursuite de feu lorsque la tâche est terminée. (C'est comment async/await fonctionne, en gros.)Remarque que je voudrais également renommer
GetResponse
àGetResponseAsync
pour plus de clarté.utilisez code ci-dessous
Task.WaitAll
bloquera de la même manière quetask.Wait
.