为什么我在“Page_Load”中注册的“页面异步任务”同步运行



我认为在Page_Load中注册的GetData任务不会阻止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.

"

Async"是一个修饰符。你总是要问"异步关于什么?

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

它不是异步的,客户端

上的页面呈现,甚至是单个请求本身 - 请求处理仍然是完全同步的,并且只会在整个响应准备就绪时发送(除非您使用显式Flush es,但这是另一罐蠕虫)。事实上,await的全部意义在于允许你的代码表现得好像它是同步的,同时在线程、I/O、UI 等方面是异步的。 await是显式同步点。

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

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

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

在完成所有工作之前,生命周期(异步时)仍然不会返回到客户端。这是一个可能更有意义的SO问答。斯科特·汉塞尔曼(Scott Hanselman)在这里给出了更好的解释。

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

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

最新更新