Search code examples
c#httpclient

How to post without awaiting with httpclient?


I'm using HttpClient to post data to a webapi application.

This code works (the web api receives the post call), but the code is waiting for a response.

public static async void Notify(List<string> txs,string url) 
{
    using (HttpClient client = new HttpClient() )
    {
        string resourceAddress = url; 
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        await client.PostAsJsonAsync(resourceAddress, txs);
    }
}

This one doesn't wait for a response from the web api but the web api doesn't get any post call:

public static void Notify(List<string> txs,string url) 
{
    using (HttpClient client = new HttpClient() )
    {
        string resourceAddress = url; 
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.PostAsJsonAsync(resourceAddress, txs);
    }
}

I need to call the web api and continue execution of code without waiting. How do I do that with HttpClient ? And I want to the method to finish execute (not include to other work inside)


Solution

  • I need to call the web api and continue execution of code without waiting. How do I do that with HttpClient ?

    When you call Notify, it should be returning a System.Threading.Task, this task is the wrapper that is managing the execution of your Notify method, and in turn the PostAsJsonAsync method.

    public static async Task Notify(List<string> txs,string url) 
    {
        using (HttpClient client = new HttpClient() )
        {
            string resourceAddress = url; 
            client.DefaultRequestHeaders.Accept.Add(
               new MediaTypeWithQualityHeaderValue("application/json"));
            return client.PostAsJsonAsync(resourceAddress, txs);
        }
    }
    

    You might be calling Notify with an await. This will pause the method calling Notify at the place of calling (and the calling method to this will continue). If you do not await you can execute other code, and then after this has completed you can then await the task from Notify and wait for the Post to finish. You will need to wait for the post to finish at somepoint, unless the extra work runs longer than the post task itself. e.g

      var task = Notify(someList, someUrl);
    
      // do a long running task / extra work here, 
      // we have not awaited Notify therefore this will execute whilst the post 
      // is running
    
      await task;
      // at this point the we have waited for the Notify method to complete, 
      // this will block for the time the post has left to complete (if any at all)
    

    await is telling your method to pause execution at this point and wait for the task to complete. BUT if there is a calling method then the calling method continues whilst it is waiting. If the calling method also awaits then this waits until the task completes, and the next method up the call stack continues, and so forth until we leave the code stack and end up in some sort of non blocking layer waiting for code to complete (e.g Async ASP.NET MVC, or Async Winforms UI). Or we have an explicit blocking Task.Wait call.