HttpClient - PostAsync doesn’t return

三世轮回 提交于 2020-07-08 00:35:35

问题


Does anyone know why HttpClient - PostAsync doesn’t return. It just does nothing. I have had it working occasionally especially for one off posts but it seems sometimes to not do anything especially under load and it doesn't throw an exception which of course makes my code unreliable and hard to debug.

I have tried adding ConfigureAwait(false) It makes not difference.

I suspect the Task is failing to 'pack'

This is in a core 3.0 console app run on macOS Catalina using visual studio code

This code is pretty much copied from Microsoft's documentation and I’m calling Microsoft Graph when posting.

public static async Task PostAsync(HttpClient httpClient, string url, string token, HttpContent content, Action<JObject> processResult, ILogger log)
    {
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
        // content.Headers.Clear();
        content.Headers.Add("Content-Type", "application/json");
        try
        {
            HttpResponseMessage response = await httpClient.PostAsync(url, content);
            if (response.IsSuccessStatusCode)
            {
                var json = await response.Content.ReadAsStringAsync();
                var result = JsonConvert.DeserializeObject(json) as JObject;
                processResult(result);
            }
            else
            {
                var errorContent = await response.Content.ReadAsStringAsync();
                log.LogError(errorContent);
            }
        }
        catch (System.Exception ex)
        {
            log.LogError(ex, ex.Message);
            throw;
        }
    }

Here is an example of the calling code

public async Task SendInvitation(string token, Invitation invitation, ILogger logger)
{
    var stringContent = new StringContent(JsonConvert.SerializeObject(invitation), Encoding.UTF8, "application/json");
    await HttpHelpers.PostAsync(
        Client,
        "https://graph.microsoft.com/v1.0/invitations",
        token,
        stringContent,
        result => logger.LogInformation(DebugHelpers.Print(result)),
        logger);
}

Answered (Sort of)

If I change

HttpResponseMessage response = await httpClient.PostAsync(url, content);

to

HttpResponseMessage response = httpClient.PostAsync(url, content).GetAwaiter().GetResult();

It seems to work but it's slow because what I'm doing is using blocking code. I think this is a quirk of core 3 on macOS. I don't like that this is happening.

More Info

I'm doing a lot of looping.

It seems that if I put all the things I'm awaiting in a taskList it behaves properly.

\\ Pseudo Code
var taskList = new List<Task>();

foreach(var thing in things){
  taskList.Add(HttpHelpers.PostAsync(...things));
}

await Task.WhenAll(taskList);


回答1:


Please check whether all calls you make in the code execution path support asynchronousity. For example once I spent quite some time figuring out a nuget package called CommandLineParser did not support async calls. I was using it like so :

public static void Main(string[] args) 
{
     Parser.Default.ParseArguments<Options>(args) 
                   .WithParsed(async options => 
                    { await httphelper.PostAsync(...); 
                    } 
}

I fixed the issue by changing it to something like

public static void Main(string[] args) 
{
     Parser.Default.ParseArguments<Options>(args) 
                   .WithParsed(options => 
                    { httphelper.PostAsync(...).Result; 
                    } 
}

So please check you are not using some calls that do not support async in the way.



来源:https://stackoverflow.com/questions/59313010/httpclient-postasync-doesn-t-return

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!