C# WebForms gridview上的异步行为
在将遗留应用程序移植到async\Wait模式时,我们遇到了一些无法跟踪的奇怪行为。我们将page async指令设置为true,并将事件处理程序添加到RowDataBound。如果EventHandler中的代码包含等待调用,则在继续处理下一行之前不会等待调用 下面是一个更容易理解的程序:C# WebForms gridview上的异步行为,c#,gridview,webforms,C#,Gridview,Webforms,在将遗留应用程序移植到async\Wait模式时,我们遇到了一些无法跟踪的奇怪行为。我们将page async指令设置为true,并将事件处理程序添加到RowDataBound。如果EventHandler中的代码包含等待调用,则在继续处理下一行之前不会等待调用 下面是一个更容易理解的程序: public partial class WorkingCorrectlyWebForm: System.Web.UI.Page { private int _index; protecte
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
为什么会这样?为什么我看不到有序的启动和退出消息。如果需要串行行为,这应该可以:
private void GridOnRowDataBound(object sender, GridViewRowEventArgs gridViewRowEventArgs)
{
if (gridViewRowEventArgs.Row.RowType != DataControlRowType.DataRow)
return;
var localIndex = ++_index;
HttpContext.Current.Response.Write($"starting #{localIndex} <br />");
Thread.Sleep(1000);
// or Task.Delay(1000).Wait();
HttpContext.Current.Response.Write($"exiting #{localIndex} <br />");
}
或者尝试:
private void GridOnRowDataBound(object sender, GridViewRowEventArgs gridViewRowEventArgs)
{
RegisterAsyncTask(new PageAsyncTask(() => Bob(gridViewRowEventArgs)));
HttpContext.Current.Response.Write($"b");
}
private async Task Bob(GridViewRowEventArgs gridViewRowEventArgs)
{
if (gridViewRowEventArgs.Row.RowType != DataControlRowType.DataRow)
return;
var localIndex = ++_index;
HttpContext.Current.Response.Write($"starting #{localIndex} <br />");
await Task.Delay(1000);
HttpContext.Current.Response.Write($"exiting #{localIndex} <br />");
}
等待任务.Delay1000只是为了重新编程。这意味着在这种情况下,任何等待的电话都不会被等待。请看“我的问题”。我在那里写道,这是可行的,但我的问题是,为什么Wait在这个场景中不能像我预期的那样工作。我怀疑这是因为您已将该方法标记为async。您希望该方法是异步的,有什么特别的原因吗?是的,因为它需要在等待的方法上等待。您不能只使用等待的方法。等等?