1

我在调用 HttpClient 类和异步调用时遇到问题。我从 page_load 调用函数 List()。调用从 HttpResponseMessage response = await client.GetAsync(str); 行返回 并且永远不会回来完成它。

我不明白我在做什么错误。以下是我的代码:

        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;
         }

它从不执行以下行。

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

请帮忙。提前致谢。

4

1 回答 1

1

你从来没有展示过任务发生了什么Page_Load,但考虑到你的症状和事实Page_Load并非如此async,我敢打赌你是在打电话ResultWait而不是在打电话await

当你这样做时,你会导致一个 deadlock。我博客的链接详细解释了这一点,但要点是await捕获和恢复当前的“上下文”。在 ASP.NET 中,这是一个请求上下文,请求上下文一次只允许一个线程在其中执行。因此,如果您调用Resultor Wait(当您在请求上下文中时),您将阻塞该请求上下文中的线程,直到Task<string>完成。同时,当HttpClient得到响应时,它会尝试在await client.GetAsync(str). 但是请求上下文一次只允许一个线程进入,并且该线程被阻塞等待Task完成。由于List上下文繁忙而无法完成,因此您遇到了死锁。

为了防止死锁,请遵循以下两个最佳实践(来自我最近的 MSDN 文章)

  1. async一路使用。也就是说,使用await代替Resultor Wait
  2. 在您的“库”代码中使用ConfigureContext(false),即await实际上List应该是await ... .ConfigureAwait(false);
于 2013-03-08T18:56:52.473 回答