Search code examples
c#asynchronoushttpclientazure-functionsazure-logic-apps

HttpClient.PostAsync continueWith not executing


I need some help figuring out why the following code in the continueWith block is not being executed for a long running service call.

     public static async void postServiceAsync(string json, string postServiceUrl, string callbackUrl, string clientId, 
                                                  string tenant, string secret, string d365Environment, TraceWriter log)
        {
            HttpClient client = new HttpClient();

            //Get authorization header
            string authHeader = await D365Authorization.getAccessToken(clientId, tenant, secret, d365Environment);
            client.DefaultRequestHeaders.Add("Authorization", authHeader);
            var httpContent = new StringContent(json);

            client.Timeout = TimeSpan.FromMinutes(90);
            client.PostAsync(postServiceUrl, httpContent).ContinueWith(async (result) =>
            {
               //call callback URL
               //This is not executed after a long running service that runs for 20 minutes.
             }
         }

The continueWith code does get run if the service execution time is short though. I thought it was a timeout issue so I added the client.Timeout value. I tried calling the service in Postman and a value is returned even after waiting for 20+ minutes. I am not using await as I want the execution to continue after calling PostAsync. I just want the continueWith callback executed after the long running service execution has completed. Thanks for your help!

The above method called postServiceAsync is called from an Azure function which is being called from an Azure Logic App http webhook action. Here is the Azure function:

public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req, TraceWriter log)
        {
            ...

            PostServiceAsync.postServiceAsync(json, shipServiceUrl, callbackUrl, clientId, tenant, secret, d365Environment, log);

            var resp = req.CreateResponse(HttpStatusCode.Accepted);
            return resp;
        }
    }

From the Azure function, I need to return the Accepted status code right away. After I've finished calling the long running service using PostAsync, I need to post to the callback URL, which is what I am doing in the continueWith block. Like I mentioned, it works if the service runtime is short. I tried Camilo's suggestion of adding await but the continueWith code did not get executed. I also tried getting rid of the continueWith and just added the code after "await client.PostAsync(...)".


Solution

  • It turns out that there is an Azure function 230 second timeout for http calls without a response. I might not be able to use an Azure function for my purposes.