异步操作超出了页面超时(尝试将HttpRequestMessage与ASP.NET WebForms页面一起使用)

时间:2018-07-24 06:11:52

标签: asp.net api web async-await

我已经在AWS中创建了一个Web API,我试图通过使用ASP.NET Webforms(最新版本)中内置的网页来获取一些JSON。我无法使异步部分正常工作。要么GET方法似乎永远挂起,要么-按照Microsoft文档中的最佳实践方法-一段时间后出现此错误:

  

[TimeoutException:异步操作超出了页面   超时。] System.Web.UI.d__554.MoveNext()+984

由于以下原因,我知道这与代码的等待/异步部分有关并且位于ASP.NET中。

  • 如果我在控制台应用程序中使用非常相似的代码,则可以正常工作。
  • 如果我使用POSTMAN调用Web API,则可以正常工作。

我在page指令中使async = true。这是我的页面加载量

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

这是我的方法

    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; 
        }
    }

上面的示例产生一个TimeoutException。在上面之前,我正在尝试以下代码。这在控制台应用程序中工作正常,但在ASP.NET页中却不行。

  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);
            }
        }
    }

我绝不是异步/等待组合的专家,但看来我使用的HttpClient没有同步替代方案,因此我必须弄清楚这一点。

1 个答案:

答案 0 :(得分:1)

我知道这是一个老问题,但我刚刚遇到。 超时很可能是由 ReadAsStringAsync 引起的,因为您忽略了在其上使用 '.ConfigureAwait(false)'。在 ASP.net 中运行异步任务可能非常挑剔,尤其是在执行上下文周围。当异步方法尝试在返回时恢复执行上下文时,它很可能是某种死锁。由于 IIS 托管的性质,这通常会失败。我不确定它是否真的是死锁或引擎盖下的其他问题。只要确保始终使用 .ConfigureAwait(false)。

我知道这是旧的,但也许它可以帮助其他人解决这个问题。