【发布时间】:2017-06-04 12:01:41
【问题描述】:
在将遗留应用程序移植到 async\await 模式时,我们遇到了一些我们无法跟踪的奇怪行为。我们将页面异步指令设置为 true,并将事件处理程序添加到 RowDataBound。如果 EventHandler 中的代码包含等待调用,则在继续处理下一行之前不会等待。
为了便于理解,这里有一个复述:
public partial class WorkingCorrectlyWebForm: System.Web.UI.Page
{
private int _index;
protected void Page_Load(object sender, EventArgs e)
{
var grid = new GridView();
grid.RowDataBound += GridOnRowDataBound;
grid.DataSource = new[]
{
new {Name = "Person1", Age = 23},
new {Name = "Person2", Age = 33},
new {Name = "Person3", Age = 15}
};
grid.DataBind();
}
private async void GridOnRowDataBound(object sender, GridViewRowEventArgs gridViewRowEventArgs)
{
if (gridViewRowEventArgs.Row.RowType != DataControlRowType.DataRow)
return;
var localIndex = ++_index;
HttpContext.Current.Response.Write($"starting #{localIndex} <br />");
await Task.Delay(1000); //HERE IS THE PROBLEMATIC LINE
//removing the remark from the following line will make code behave "synchronously" as expected.
// Task.Delay(1000).Wait();
HttpContext.Current.Response.Write($"exiting #{localIndex} <br />");
}
}
此代码将生成与此类似的输出(而不是按顺序“开始\退出”每个项目):
从 #1 开始
从 #2 开始
从 #3 开始
退出#3
退出#1
退出#2
为什么会这样?为什么我没有看到有序的“开始”和“退出”消息。
【问题讨论】: