为什么我的`PageAsyncTask`在`Page_Load`中同步运行?

时间:2016-04-26 10:49:37

标签: c# asp.net asynchronous

我认为GetData中注册的Page_Load任务不会阻止加载Index.aspx,因为它是异步任务;在呈现页面5秒后,lblData被设置并反映在Index.aspx

但是,在我的情况下,Index.aspx的加载被阻止5秒,等待异步GetData完成。仅在5秒后呈现Index.aspx

这是预期的吗?或者GetData正在同步运行,因为我做错了什么?

// Index.aspx.cs
public partial class Index : Page
{
    protected string lblData;
    protected void Page_Load(object sender, EventArgs e)
    {
        RegisterAsyncTask(new PageAsyncTask(GetData));
        ExecuteRegisteredAsyncTasks();
    }

    public async Task GetData()
    {
        await Task.Delay(5000);
        lblData = "Hello world!";
    }
    // ...
}

我已将Async="true"添加到Index.aspx

3 个答案:

答案 0 :(得分:5)

“异步”是一个修饰符。你总是要问“与什么异步?”

在这种情况下,任务对于为请求提供服务的工作线程是异步的。重要的一点是,在处理大多数异步任务时,您不需要阻止请求线程,因此您的服务器将能够同时处理更多请求,同时可能使用更少的资源来执行此操作。

它与客户端上的页面呈现不同步,甚至不是单个请求本身 - 请求处理仍然是完全同步的,只有在整个响应准备就绪时才会发送(除非你使用显式{{1}但是,这是另一种蠕虫病毒)。事实上,Flush的重点是允许你的代码表现得像是同步的,而对于线程,I / O,UI,你有什么异步。 await是显式同步点。

事实上,这正是您首先使用异步基础架构的原因。如果您使用异步任务而不是 await,请求将在响应完成之前结束。基础结构允许您在不需要时释放工作线程,同时在异步工作返回时保持所有相关的请求上下文准备就绪。它类似于在控制台应用程序的RegisterAsyncTask方法中使用await - 如果基础架构尚未就绪,Main只是意味着await没有“并且在任务完成“。

如果您想要一些不阻止请求处理的东西,它必须是与请求相关的异步。例如,页面可以向服务器发送单独的AJAX请求以提供更多数据。

答案 1 :(得分:1)

根据MSDN,你正在做的一切正确。我假设您错误地假设在GetData函数中定义的异步操作完成之前,页面将被加载/呈现并返回到客户端 - 如果这样做是错误的。

生命周期(虽然异步)在完成所有工作之前仍然没有返回客户端。这是SO Q & A,可能更有意义。来自Scott Hanselman的更好解释here

答案 2 :(得分:0)

它可能是异步运行的,但它仍然是"后面的代码",并且在将任何呈现的页面发送到浏览器之前,将在服务器上运行并完成后面的代码。

如果您希望在页面加载到浏览器后动态填充网格,则需要使用JavaScript和WebMethods或WebAPI或类似的东西。