【发布时间】:2016-06-20 15:14:38
【问题描述】:
我刚刚在 asp.net 上遇到并发编码,发现有两种方法可以在 Page_Load 方法中触发异步方法
- RegisterAsyncTask(new PageAsyncTask(DoSthAsync()));
- 等待 DoSthAsync();
但是,它们有不同的操作结果。对于案例 1,RegisterAsyncTask 之后的代码将在 DoSthAsync() 中的任何代码之前立即运行。而 await 之后的代码将在 DoSthAsync() 完成时运行。
例如:
//protected async void Page_Load(object sender, EventArgs e)
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("Start</br>");
Response.Flush();
RegisterAsyncTask(new PageAsyncTask(DoSthAsync()));
//await DoSthAsync();
Response.Write("End</br>");
Response.Flush();
}
public async Task LoadSomeData()
{
await Task.Delay(1000);
Response.Write("Do Sth Async</br>");
Response.Flush();
}
这段代码sn-p会产生如下结果:
Start
End
Do Sth Async *(after 1 second delay)*
当我取消注释 await DoSthAsync() 代码并注释 RegisterAsyncTask 时,将显示以下结果。
Start
Do Sth Async *(after 1 second delay)*
End
在 Rick Anderson 的文章 Using Asynchronous Methods in ASP.NET 4.5 中,他建议使用 RegisterAsyncTask 可以更好地控制代码执行。但是,这会产生一个我正在寻找的意外结果,而 page_load 中的 await 将生成相同的结果,因为我在 Windows 程序中尝试类似的代码序列。
在他的文章中,Rick 还提供了在 GetPWGsrvAsync() 触发之前启动秒表的代码,并在所有异步代码完成后停止显示代码执行了多长时间。它在屏幕截图中显示经过的时间为 0.872 秒。因此,在所有先前的代码(包括所有异步方法)完成后,预计秒表会停止。
.......
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
RegisterAsyncTask(new PageAsyncTask(DoSthAsync()));
//await DoSthAsync();
stopWatch.Stop();
Response.Write(String.Format("Elapsed time:{0}",stopWatch.Elapsed.Milliseconds / 1000.0));
Response.Write("</br>");
Response.Flush();
.......
虽然我按照与上面的代码 sn-p 相同的方式进行操作,但在 RegisterAsyncTask 或 await DoSthAsync() 中得到不同的结果。虽然 经过时间 显示在不同的位置,但它们都给了我非常短的经过时间,大约 0.010s 或 10+ms 并且相信秒表在异步函数 DoSthAsync() 被解雇。其实窗口程序也有类似的结果,很快就停止了。
在对问题进行了长篇描述之后,我想问一下异步编码的哪种方式具有更好的控制和代码模式。在这两者之间,我怎么能期望秒表的结果给我准确的代码经过时间。
【问题讨论】:
标签: c# asp.net concurrency async-await task-parallel-library