[英]Using HttpClient.GetAsync to call Web API seems to hang
我正在研究概念驗證原型。
我有Asp.Net C#web表單(Visual Studio 2013,.Net 4.5)頁面。 在按鈕上單擊我做這樣的事情:
List<Blog> blogs = null;
protected void btnLoadData_Click(object sender, EventArgs e)
{
//...;
switch (int.Parse(rblDataSource.SelectedValue))
{
//...;
case 4:
RunAsyncBlogs().Wait();
break;
default:
blogs = localGetter.GetBlogs();
break;
}
//...;
}
RunAsyncBlogs如下所示:
static async Task RunAsyncBlogs()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost/wapiDemo/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP GET
HttpResponseMessage response = await client.GetAsync("api/Blogs");
if (response.IsSuccessStatusCode)
{
List<Blog> thisBlogList = await response.Content.ReadAsAsync<List<Blog>>();
var cnt = thisBlogList.Count();
}
}
}
代碼在response = await client.GetAsync調用處停止。 當我說它停止時,調試器就像請求已經結束,但瀏覽器仍在等待。
如果我運行一個控制台應用程序(我將RunAsync()方法復制並粘貼到其中),它以相同的方式調用Web API,我得到了我的數據。 所以,我相信Web API應用程序正在按預期響應。
這個:
RunAsyncBlogs().Wait();
你的代碼陷入僵局。 它同步阻止您的異步方法調用,該調用嘗試將繼續編組回隱式捕獲的同步上下文。 這就是為什么你不應該阻止異步代碼
protected async void btnLoadData_Click(object sender, EventArgs e)
{
// Other stuff
await RunAsyncBlogs();
}
問題是你必須嵌套async
方法。 RunAsyncBlogs
和response.Content.ReadAsAsync<List<Blog>>();
在里面。
在以下行的末尾添加.ConfigureAwait(false)
將阻止代碼掛起:
var thisBlogList = await response.Content.ReadAsAsync<List<Blog>>().ConfigureAwait(false);
但是,即使這將解決阻塞,代碼仍將同步執行,因為btnLoadData_Click
方法中的Wait()
調用。
如前所述,切換到異步執行是更好的解決方案。
您的按鈕單擊事件需要是異步的。
protected async void btnLoadData_Click(object sender, EventArgs e)
{
//...;
switch (int.Parse(rblDataSource.SelectedValue))
{
//...;
case 4:
await RunAsyncBlogs();
break;
default:
blogs = localGetter.GetBlogs();
break;
}
//...;
}
請參閱有關處理異步阻止問題的帖子。
http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
是VS2013的Web應用程序與WEbAPi和MVC在MVC我有鏈接到這個:
public JsonResult GetWithHttpClient()
{
Employee employee = null;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(path);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("api/Employees/12345").Result;
//the IsSuccessStatusCode property is false if the status is an error code.
//All the error: {StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:{ Pragma: no-cache X-SourceFiles: =?UTF-8?B?QzpcRkFCSU9fQ09ESUNFXE15RXhhbXBsZVxXZWJBcHBsaWNhdGlvbjFcV2ViQXBwbGljYXRpb24xXGFwaVxFbXBsb3llZXNcMTIzNDU=?= Cache-Control: no-cache Date: Tue, 28 Jul 2015 14:47:03 GMT Server: Microsoft-IIS/8.0 WWW-Authenticate: Bearer X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Content-Length: 61 Content-Type: application/json; charset=utf-8 Expires: -1}}
if (response.IsSuccessStatusCode)
{
employee = response.Content.ReadAsAsync<Employee>().Result;
}
}
return Json (employee, JsonRequestBehavior.AllowGet);
}
WebApi稱為EmployeesController。 我有這個方法:
public Employee Get(int id)
{
return list.First(e => e.Id == id);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.