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

异步操作超过了页面超时时间(尝试将HttpRequestMessage与ASP.NET WebForms页面一起使用),asp.net,api,web,async-await,Asp.net,Api,Web,Async Await,我已经在AWS中创建了一个web API,我正在尝试使用ASP.NET Webforms(最新版本)中构建的网页获取一些JSON。我无法让异步部分工作。要么GET方法看起来永远挂起,要么——遵循Microsoft文档中的最佳实践方法——过了一会儿我发现这个错误: [TimeoutException:异步操作超出了页面 超时。]System.Web.UI.d_u554.MoveNext()+984 我知道这与代码的wait/async部分有关,并且由于以下原因而位于ASP.NET中 如果我在控制

我已经在AWS中创建了一个web API,我正在尝试使用ASP.NET Webforms(最新版本)中构建的网页获取一些JSON。我无法让异步部分工作。要么GET方法看起来永远挂起,要么——遵循Microsoft文档中的最佳实践方法——过了一会儿我发现这个错误:

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

我知道这与代码的wait/async部分有关,并且由于以下原因而位于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);
            }
        }
    }
类程序
{
静态void Main(字符串[]参数)
{
尝试
{
MainAsync().Wait();
}
捕获(例外情况除外)
{
WriteLine($“发生异常{ex.Message}”);
Console.ReadKey();
}
}
静态异步任务mainsync()
{
尝试
{
var signer=新的AWS4RequestSigner(“AccessKey”、“SecretKey”);
var请求=新的HttpRequestMessage
{
Method=HttpMethod.Get,
RequestUri=新的Uri(“https://.execute-api.ap-southeast-2.amazonaws.com/Prod/tables/InSiteStoreInformation/ServerName")
};
请求=等待签名者签名(请求“执行api”、“ap-2”);
var client=新的HttpClient();
var response=wait client.sendaync(请求);
var responsest=await response.Content.ReadAsStringAsync();
dynamic sales=Newtonsoft.Json.JsonConvert.DeserializeObject(responsest);
Console.WriteLine($“Server={sales[0].ServerName}”);
Console.ReadKey();
Console.Write(responsest);
Console.ReadKey();
}
捕获(例外情况除外)
{
投掷(ex);
}
}
}

我绝对不是异步/等待组合方面的专家,但我使用的HttpClient似乎没有同步替代方案,所以我必须弄清楚这一点

我知道这是个老生常谈的问题,但我只是碰巧遇到了。 超时最有可能是由ReadAsStringAsync引起的,因为您忽略了对其使用“.ConfigureAwait(false)”。在ASP.net中运行异步任务可能非常挑剔,尤其是在执行上下文中。当异步方法试图在返回时恢复执行上下文时,它很可能是某种类型的死锁。由于IIS托管的性质,这通常会失败。我不确定这到底是一个死锁还是其他问题。只需确保始终使用.ConfigureAwait(false)


我知道这很古老,但也许它能帮助其他人遇到这个问题。

我应该指出,我整天都在用头撞砖墙。我就是不能让它工作。这很令人沮丧,因为我花了大量时间建立了一个非常好的web API,我可以使用路径参数等来调用它,但我的整个计划都依赖于提供一个轻量级的ASP.NET Webforms前端,它只需要使用web API、获取JSON并基于JSON数据呈现页面。我不明白为什么我不能像在控制台应用程序“test”中一样使用HttpRequestMessage。不确定您的
注册表同步任务对
getAsync()
有什么作用,但由于它似乎永远挂起,可能与所描述的死锁有关。如果
GetAsync()
将在
Page\u Load
上立即被调用,您可以尝试使事件方法异步并等待
GetAsync()
。您是否尝试过使用类似Fiddler的工具来查看线路上发生了什么?嗨,Paulo,我尝试过Fiddler,它显示了对URL的状态200调用,但我可以确认它从未到达web API,因为它在调用时记录了哪些记录,并且从未触发任何事件。我将再次尝试Fiddler并提供问题中的输出。迈克尔,我读过很多关于死锁场景的书,也尝试过一些不同的方法,但似乎都不管用。我想我可能已经试过了你的建议,但我会具体地做,如果不起作用,我会用我尝试的代码再次更新我的问题。有没有人可以向我展示一个从asp.net页面向web api使用HttpRequest消息的示例?一个有效的,理论上我可以使用的(因此,如果它不起作用,我知道它不是代码本身,可能是环境或其他东西)。我在这里不知所措,但我必须让它工作起来