简体   繁体   English

在ASP.NET中的HttpClient调用

[英]HttpClient call in asp.net

I am facing problem in calling HttpClient class and async call. 我在调用HttpClient类和异步调用时遇到问题。 I call the function List() from page_load. 我从page_load调用函数List()。 The calls return from the line HttpResponseMessage response = await client.GetAsync(str); 调用从HttpResponseMessage响应=等待客户端返回。GetAsync(str); and never comes back to finish it. 永远不会回来完成它。

I don't understand what mistake I am doing. 我不明白我在做什么错。 Following is my code: 以下是我的代码:

        protected void Page_Load(object sender, EventArgs e)
        {
            Task<string> s= List(product); 
        }

        protected async Task<string> List(string ProductType)
        {
            string str = "http://xx.xx.com/wiki/api.php";


            using (HttpClient client = new HttpClient())
            {
                client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", "username", "password"))));
                HttpResponseMessage response = await client.GetAsync(str);

                response.EnsureSuccessStatusCode();

                string content = await response.Content.ReadAsStringAsync();
            }
            return content;
         }

It never executes following lines. 它从不执行以下几行。

response.EnsureSuccessStatusCode();
string content = await response.Content.ReadAsStringAsync();

Please help. 请帮忙。 Thanks in advance. 提前致谢。

You never show what happens to the task in Page_Load , but given your symptoms and the fact that Page_Load is not async , I'm betting that you're calling Result or Wait instead of await ing it. 您永远不会在Page_Load显示该任务发生了什么,但是鉴于您的症状以及Page_Loadasync的事实,我敢打赌您正在调用ResultWait而不是await它。

When you do that, you cause a deadlock . 当您这样做时,将导致死锁 The link to my blog explains this in detail, but the gist is that await will capture and restore the current "context". 我博客的链接对此进行了详细说明,但要点是await将捕获并恢复当前的“上下文”。 In ASP.NET, this is a request context, and the request context only allows one thread executing in it at a time. 在ASP.NET中,这是一个请求上下文,并且请求上下文一次仅允许一个线程在其中执行。 So, if you call Result or Wait (while you're in the request context), you'll block a thread in that request context until the Task<string> completes. 因此,如果调用ResultWait (当您处于请求上下文中),则将在该请求上下文中阻塞线程,直到Task<string>完成。 Meanwhile, when the HttpClient gets its response, it tries to resume after the await client.GetAsync(str) . 同时,当HttpClient收到响应时,它将尝试在await client.GetAsync(str)之后恢复。 But the request context will only allow one thread in at a time, and that thread is blocked waiting for the Task to complete. 但是请求上下文一次只允许一个线程进入,并且该线程被阻塞,等待Task完成。 Since List cannot complete because the context is busy, you have a deadlock. 由于上下文繁忙, List无法完成,因此您陷入了僵局。

To prevent deadlocks, follow these two best practices (from my recent MSDN article) : 为防止死锁,请遵循以下两个最佳实践(来自我最近的MSDN文章)

  1. Use async all the way. 一路使用async That is, use await instead of Result or Wait . 也就是说,使用await代替ResultWait
  2. Use ConfigureContext(false) in your "library" code, ie, every await in List should actually be await ... .ConfigureAwait(false); 在您的“库”代码中使用ConfigureContext(false) ,即List每个await实际上应该是await ... .ConfigureAwait(false);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM