Modifier: Cette question semble être le même problème, mais n'a pas de réponses...
Modifier: Dans le cas de test 5, la tâche semble être bloquée dans l'état WaitingForActivation
.
J'ai rencontré un comportement étrange en utilisant System.Net.Http.HttpClient dans .NET 4.5 - où "attendre" le résultat d'un appel à (par exemple) httpClient.GetAsync(...)
ne renverra jamais.
Cela ne se produit que dans certaines circonstances lors de l'utilisation de la nouvelle fonctionnalité de langage async/await et de l'API Tasks - le code semble toujours fonctionner lorsque seules les continuations sont utilisées.
Voici un code qui reproduit le problème - ajoutez ceci dans un nouveau "projet WebApi MVC 4" dans Visual Studio 11 pour exposer les points d'extrémité GET suivants :
/api/test1
/api/test2
/api/test3
/api/test4
/api/test5 <--- ne se termine jamais
/api/test6
Chacun des points d'extrémité ici renvoie les mêmes données (les en-têtes de réponse de stackoverflow.com) sauf /api/test5
qui ne se termine jamais.
Ai-je rencontré un bug dans la classe HttpClient, ou est-ce que j'utilise mal l'API d'une manière ou d'une autre ?
Code pour reproduire :
public class BaseApiController : ApiController
{
///
/// Récupère des données en utilisant des continuations
///
protected Task Continuations_GetSomeDataAsync()
{
var httpClient = new HttpClient();
var t = httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead);
return t.ContinueWith(t1 => t1.Result.Content.Headers.ToString());
}
///
/// Récupère des données en utilisant async/await
///
protected async Task AsyncAwait_GetSomeDataAsync()
{
var httpClient = new HttpClient();
var result = await httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead);
return result.Content.Headers.ToString();
}
}
public class Test1Controller : BaseApiController
{
///
/// Gère la tâche en utilisant Async/Await
///
public async Task Get()
{
var data = await Continuations_GetSomeDataAsync();
return data;
}
}
public class Test2Controller : BaseApiController
{
///
/// Gère la tâche en bloquant le thread jusqu'à ce que la tâche se termine
///
public string Get()
{
var task = Continuations_GetSomeDataAsync();
var data = task.GetAwaiter().GetResult();
return data;
}
}
public class Test3Controller : BaseApiController
{
///
/// Passe la tâche au contrôleur hôte
///
public Task Get()
{
return Continuations_GetSomeDataAsync();
}
}
public class Test4Controller : BaseApiController
{
///
/// Gère la tâche en utilisant Async/Await
///
public async Task Get()
{
var data = await AsyncAwait_GetSomeDataAsync();
return data;
}
}
public class Test5Controller : BaseApiController
{
///
/// Gère la tâche en bloquant le thread jusqu'à ce que la tâche se termine
///
public string Get()
{
var task = AsyncAwait_GetSomeDataAsync();
var data = task.GetAwaiter().GetResult();
return data;
}
}
public class Test6Controller : BaseApiController
{
///
/// Passe la tâche au contrôleur hôte
///
public Task Get()
{
return AsyncAwait_GetSomeDataAsync();
}
}
2 votes
Il ne semble pas que ce soit le même problème, mais juste pour vous informer, il y a un bug MVC4 dans la version bêta concernant les méthodes asynchrones qui se terminent de manière synchrone - voir stackoverflow.com/questions/9627329/…
0 votes
Merci - je vais faire attention à cela. Dans ce cas, je pense que la méthode devrait toujours être asynchrone en raison de l'appel à
HttpClient.GetAsync(...)
?