HttpClient.SendAsync 方法退出而不抛出异常

Posted

技术标签:

【中文标题】HttpClient.SendAsync 方法退出而不抛出异常【英文标题】:HttpClient.SendAsync method exits without throwing exception 【发布时间】:2016-11-08 06:22:18 【问题描述】:

我正在调用以下函数来获取访问令牌,以便使用 REST Api 检索 Twitter 用户配置文件。

  public async Task<string> GetAccessToken()
    
        try
        
            var httpClient = new HttpClient();
            var request = new HttpRequestMessage(HttpMethod.Post, "https://api.twitter.com/oauth2/token ");
            var customerInfo = Convert.ToBase64String(new UTF8Encoding().GetBytes(OAuthConsumerKey + ":" + OAuthConsumerSecret));
            request.Headers.Add("Authorization", "Basic " + customerInfo);
            request.Content = new StringContent("grant_type=client_credentials", Encoding.UTF8, "application/x-www-form-urlencoded");

            //program exits at this point 
            HttpResponseMessage response = await httpClient.SendAsync(request).ConfigureAwait(false);
            string json = await response.Content.ReadAsStringAsync();
            var serializer = new javascriptSerializer();
            dynamic item = serializer.Deserialize<object>(json);
            return item["access_token"];
        
        catch (Exception ex)
        
            MessageBox.Show("In  Retrieving access token : " + ex.ToString());
        

    

程序退出/终止,在调用HttpResponseMessage response = await httpClient.SendAsync(request).ConfigureAwait(false); 时未检索到响应。

这是调用GetAccessToken()

的父函数
public async Task getUserProfile(string userName)
    
        try
        
            if (accessToken == null)
            
                accessToken = await GetAccessToken().ConfigureAwait(false);
            

            var request = new HttpRequestMessage(HttpMethod.Get, string.Format(" https://api.twitter.com/1.1/users/show.json?screen_name=0", userName));
            request.Headers.Add("Authorization", "Bearer " + accessToken);
            var httpClient = new HttpClient();
            HttpResponseMessage response = await httpClient.SendAsync(request).ConfigureAwait(false);
            var jsonString = await response.Content.ReadAsStringAsync();

            var serializer = new JavaScriptSerializer();
            dynamic jsonObj = serializer.Deserialize<object>(jsonString);

        

        catch (Exception ex)
        
            if (DEBUG)
            
                MessageBox.Show("In  Retrieving user profile from twitter : " + ex.ToString());
            

        

    

我无法捕获程序为何在 GetAccessToken() 或 getUserProfile() 退出的异常。但是,如果 getUserProfile() 将 Task&lt;IEnumerable&lt;string&gt;&gt; 作为返回类型,则代码会成功执行并检索 HttpResponseMessage。为什么会出现这个问题?如何捕获异常?

【问题讨论】:

如你所说,你的方法是异步的......当任务将被执行/完成时会发生异常。是否需要使用异步方法? 你能显示调用getUserProfile的代码吗?这是什么类型的应用程序? 想知道你为什么在那里使用 JavaScriptSerializer?微软的documentation 上面写着“Json.NET 应该用于 [用于] 序列化和反序列化。为支持 AJAX 的应用程序提供序列化和反序列化功能。” @Paulo Morgado getUserProfile() 使用函数public void getTwitterInfo() var twitter = new Twitter("consumerKey","consumerSecret"); twitter.getUserProfile(userName); 调用 所以,您不必等待它完成。它是控制台应用程序吗? 【参考方案1】:

您的应用程序永久退出,因为您没有等待getUserProfile() 完成。您可以将getTwitterInfo 标记为与其他类似的异步或告诉它等待任务完成

public async Task getTwitterInfo()  
    var twitter = new Twitter("consumerKey","consumerSecret");
    await twitter.getUserProfile(userName); 

public void getTwitterInfo()  
    var twitter = new Twitter("consumerKey","consumerSecret");
    var task = twitter.getUserProfile(userName); 
    var result = task.WaitAndUnwrapException();

【讨论】:

谢谢。我也发现了问题并像这样解决了 `var userProfile= twitter.getUserProfile(userName).Result() `【参考方案2】:

你试过了吗

    HttpResponseMessage response = httpClient.SendAsync(request).Result;

我自己的代码也有同样的问题,这似乎已经解决了,应该等同于原来的调用。不过,我仍然不明白崩溃的根本原因。

【讨论】:

以上是关于HttpClient.SendAsync 方法退出而不抛出异常的主要内容,如果未能解决你的问题,请参考以下文章

在 HttpClient.SendAsync() 之后无法访问已释放的对象

HttpClient.SendAsync() 未将 JSON 作为字符串发送

HttpClient.SendAsync 不发送请求正文

HttpClient SendAsync

模拟 HttpClient.SendAsync 以返回内容不为空的响应

HttpClient.SendAsync:500 - Windows 服务应用程序中的内部服务器错误