Best practice for making a HTTP Post from asp.net Page_Load?

Viewed 410

Seems like simple task, but the interwebs are flooded with different ways to approach this, so what is best practice for making a simple HTTP POST from asp.net Page_Load (I'm on .net 4.7) ?

Many resources point to the fact that HttpClient.PostAsync is the most lightweight approach.

However, the example here: https://docs.microsoft.com/en-us/aspnet/web-forms/overview/performance-and-caching/using-asynchronous-methods-in-aspnet-45 - uses WebClient.

Also, both of theses approaches require setting Page Async="true" on the page - I am seeing conflicting information on whether this is actually the right approach.

Context: My page looks like it is spending a lot of time in BLOCKED_TIME during two requests that are made in Page_Load.

enter image description here

I suspect this is due to the way I currently make the POST:

public string makePost(string parametersToPassOn, string command)
{
    HttpContent c = new StringContent(parametersToPassOn, Encoding.UTF8, "application/json");
    var t = Task.Run(() => fireRESTcall(new Uri(walletProxyURL + command), c));
    t.Wait();

    return t.Result;
}

static async Task<String> fireRESTcall(Uri u, HttpContent c)
{
    var response = string.Empty;
    using (var client = new HttpClient())
    {
        HttpRequestMessage request = new HttpRequestMessage
        {
            Method = HttpMethod.Post,
            RequestUri = u,
            Content = c
        };

        HttpResponseMessage result = await client.SendAsync(request);
        if (result.IsSuccessStatusCode)
        {
            response = await result.Content.ReadAsStringAsync();
        }
    }
    return response;
}

Any help/thoughts would be greatly appreciated.

1 Answers

During the time your page makes an outgoing HTTP request, it can't do anything useful other than waiting for the response. See also Understanding BLOCKED_TIME in PerfView

You probably can't do anything about this delay, as you need the external API for some data, and you need to wait for it to complete in order to do something useful with that data.

So it's advisable to use async/await all the way, using RegisterAsyncTask():

void Page_Load()
{
    RegisterAsyncTask(new PageAsyncTask(CallApiAsync));
    Page.ExecuteRegisteredAsyncTasks();
}

async Task CallApiAsync() // calls
async Task<string> MakePost() // calls
async Task<String> FireRESTcall()

This frees up the thread to handle a new incoming request, until the outgoing request is finished and the incoming request continues on the same or another thread pool thread.

For this to work with WebForms, you do need Async="true" on your page.

Related