編集: この質問は同じ問題のようですが、回答がありません...
編集:テストケース5では、タスクが停止したように見えますWaitingForActivation
。
.NET 4.5でSystem.Net.Http.HttpClientを使用していくつかの奇妙な動作に遭遇しました-(たとえば)への呼び出しの結果を「待機」することhttpClient.GetAsync(...)
は決して戻りません。
これは、新しいasync / await言語機能とTasks APIを使用する特定の状況でのみ発生します。継続のみを使用する場合、コードは常に機能するようです。
これが問題を再現するコードです。これをVisual Studio 11の新しい「MVC 4 WebApiプロジェクト」にドロップして、次のGETエンドポイントを公開します。
/api/test1
/api/test2
/api/test3
/api/test4
/api/test5 <--- never completes
/api/test6
ここの各エンドポイントは、/api/test5
決して完了しないことを除いて、同じデータ(stackoverflow.comからの応答ヘッダー)を返します。
HttpClientクラスでバグが発生したか、または何らかの方法でAPIを誤用していますか?
再現するコード:
public class BaseApiController : ApiController
{
/// <summary>
/// Retrieves data using continuations
/// </summary>
protected Task<string> Continuations_GetSomeDataAsync()
{
var httpClient = new HttpClient();
var t = httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead);
return t.ContinueWith(t1 => t1.Result.Content.Headers.ToString());
}
/// <summary>
/// Retrieves data using async/await
/// </summary>
protected async Task<string> 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
{
/// <summary>
/// Handles task using Async/Await
/// </summary>
public async Task<string> Get()
{
var data = await Continuations_GetSomeDataAsync();
return data;
}
}
public class Test2Controller : BaseApiController
{
/// <summary>
/// Handles task by blocking the thread until the task completes
/// </summary>
public string Get()
{
var task = Continuations_GetSomeDataAsync();
var data = task.GetAwaiter().GetResult();
return data;
}
}
public class Test3Controller : BaseApiController
{
/// <summary>
/// Passes the task back to the controller host
/// </summary>
public Task<string> Get()
{
return Continuations_GetSomeDataAsync();
}
}
public class Test4Controller : BaseApiController
{
/// <summary>
/// Handles task using Async/Await
/// </summary>
public async Task<string> Get()
{
var data = await AsyncAwait_GetSomeDataAsync();
return data;
}
}
public class Test5Controller : BaseApiController
{
/// <summary>
/// Handles task by blocking the thread until the task completes
/// </summary>
public string Get()
{
var task = AsyncAwait_GetSomeDataAsync();
var data = task.GetAwaiter().GetResult();
return data;
}
}
public class Test6Controller : BaseApiController
{
/// <summary>
/// Passes the task back to the controller host
/// </summary>
public Task<string> Get()
{
return AsyncAwait_GetSomeDataAsync();
}
}
HttpClient.GetAsync(...)
?への呼び出しのため、メソッドは常に非同期である必要があると思います。