2

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://learn.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.

ThomasN
  • 49
  • 5
  • Async isn't needed for a simple request/response if you are just waiting for a response and not doing anything else. await is need since you have to wait until the entire response is received before processing the response. – jdweng Aug 03 '20 at 14:57
  • That's my thinking as well. But then why is so much time spent in BLOCKED_TIME ? – ThomasN Aug 03 '20 at 15:05
  • You may be waiting for a proxy. when you do not need to use proxy. The default request has proxy set so often you end up waiting 30 seconds for a proxy to timeout and then connect properly. – jdweng Aug 03 '20 at 15:12
  • @jdweng why do you keep doing [this](https://meta.stackoverflow.com/questions/392514/what-can-i-do-about-a-user-consistently-spreading-misinformation)? _"The default request has proxy set so often you end up waiting 30 seconds for a proxy to timeout and then connect properly"_ - a new `HttpClient()` or `WebClient()` has **no** proxy set by default (unless your system has), and if either _does_ have an unreachable proxy configured, they do **not** retry the request without a proxy after the timeout. – CodeCaster Aug 03 '20 at 15:23

1 Answers1

1

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.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272