簡體   English   中英

使用HttpClient.GetAsync來調用Web API似乎掛了

[英]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方法。 RunAsyncBlogsresponse.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM