我认为在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 或类似的东西。