lundi 23 juillet 2018

An asynchronous operation exceeded the page timeout (trying to use HttpRequestMessage with ASP.NET WebForms page)

I have created a web API in AWS that I am trying to get some JSON back from using a web page built in ASP.NET Webforms (most up-to-date version). I can't get the asynchronous part to work. Either the GET method hangs seemingly forever, or - following the best practice approach from the Microsoft documentation - I get this error after a little while:

[TimeoutException: An asynchronous operation exceeded the page timeout.] System.Web.UI.d__554.MoveNext() +984

I know this is something to do with the wait/async portion of the code and being in ASP.NET because of the following.

  • If I use very similar code in a console application it works fine.
  • If i call the web API using POSTMAN it works fine.

I have made async = true in the page directive. Here is my page load

protected void Page_Load(object sender, EventArgs e)
{
    try
    {
        RegisterAsyncTask(new PageAsyncTask(GetStuffAsync));
    }
    catch (Exception ex)
    {
        renderStoreCards.Text = ex.Message;
    }
}

Here is my method

    private async Task GetStuffAsync()
    {
        string testHtml = string.Empty;

        try
        {
            var signer = new AWS4RequestSigner("AccessKey", "SecretKey");
            var request = new HttpRequestMessage
            {
                Method = HttpMethod.Get,
                RequestUri = new Uri("https://some-aws-address-changed-for-stack-overflow.execute-api.ap-southeast-2.amazonaws.com/Prod/tables/InSiteStoreInformation/ServerName")
            };

            request = await signer.Sign(request, "execute-api", "ap-southeast-2");
            var client = new HttpClient();
            var response = await client.SendAsync(request).ConfigureAwait(false);
            string responseString = await response.Content.ReadAsStringAsync();
        }
        catch (Exception ex)
        {
            renderStoreCards.Text = ex.Message; 
        }
    }

The above example produces a TimeoutException. Previous to the above, I was trying the following code. This works fine in a console app, but not in the ASP.NET page.

  class Program
    {
        static void Main(string[] args)
        {
            try
            {
                MainAsync().Wait();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Exception occured {ex.Message}");
                Console.ReadKey();
            }
        }

        static async Task MainAsync()
        {
            try
            {
                var signer = new AWS4RequestSigner("AccessKey", "SecretKey");
                var request = new HttpRequestMessage
                {
                    Method = HttpMethod.Get,
                    RequestUri = new Uri("https://<Hiddenforstackoverflowpost>.execute-api.ap-southeast-2.amazonaws.com/Prod/tables/InSiteStoreInformation/ServerName")
                };

                request = await signer.Sign(request, "execute-api", "ap-southeast-2");

                var client = new HttpClient();
                var response = await client.SendAsync(request);

                var responseStr = await response.Content.ReadAsStringAsync();
                dynamic sales = Newtonsoft.Json.JsonConvert.DeserializeObject(responseStr);
                Console.WriteLine($"Server = {sales[0].ServerName}");
                Console.ReadKey();
                Console.Write(responseStr);
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }
    }

I am by no means an expert in async/wait combinations, but it appears that the HttpClient I'm using has no synchronous alternative, so I have to figure this out.




Aucun commentaire:

Enregistrer un commentaire