我一直在 WebForms 中测试异步,这一次,我的问题不是关于如何做某事,而是关于已经工作的东西如何工作。这是我的测试代码:
protected override void OnPreRender(EventArgs e)
{
Response.Write("OnPreRender<Br>");
}
protected override void OnPreRenderComplete(EventArgs e)
{
Response.Write("OnPreRenderComplete<Br>");
}
protected async override void OnLoadComplete(EventArgs e)
{
Response.Write("OnLoadComplete<br>");
var t1 = Task.Factory.StartNew(() => {
System.Threading.Thread.Sleep(2000);
return 1;
});
//This actually does run:
Response.Write((await t1).ToString());
}
所以我的任务暂停了一会儿,然后写出结果。我的问题是 - 我不希望这会起作用,因为 OnLoadComplete 方法已经产生了控制权 - 我希望页面实际上完成渲染并在我的任务返回之前返回给客户端。
实际输出为:
OnLoadComplete
OnPreRender
1OnPreRenderComplete
因此很明显,OnLoadComplete 方法产生了控制权,以便 OnPreRender 可以运行,然后控制权返回给 OnLoadComplete。我的预期结果是“1”永远不会打印,因为随后的事件会触发,并且页面的线程会被杀死,或者在发送响应后会发生任务后写入。我想,鉴于上述情况,即使我延迟 10 秒,结果也完全一样,这并不奇怪。
我假设 WebForm 引擎中有一些连接可确保在页面生命周期的下一阶段继续之前完成所有等待项。有谁知道这是怎么发生的?我害怕在需要在其他事件之前完成的方法中使用 async/await,因为担心继续为时已晚,但如果它是内部处理的,那我就不用担心了。