我只是遇到併發編碼在asp.net,發現有2種方式來觸發在Page_Load方法ASP.NET異步任務執行序列
- RegisterAsyncTask異步方法(新PageAsyncTask(DoSthAsync())) ;
- await DoSthAsync();
然而,他們有不同的操作結果。對於案例1,RegisterAsyncTask之後的代碼將立即在DoSthAsync()中的任何代碼之前運行。雖然等待後的代碼將在完成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();
}
該代碼段將產生以下結果:
Start
End
Do Sth Async *(after 1 second delay)*
雖然我去掉等待DoSthAsync()代碼和註釋RegisterAsyncTask,下面的結果將是所示。
Start
Do Sth Async *(after 1 second delay)*
End
在裏克·安德森的文章Using Asynchronous Methods in ASP.NET 4.5,他建議使用RegisterAsyncTask會給代碼執行的更好的控制。然而,這給了一個意想不到的結果,我期待在page_load等待將生成相同的一個,因爲我嘗試在Windows程序中的類似代碼序列。
在他的文章中,裏克也有GetPWGsrvAsync前秒錶開始的代碼()發射,並停止畢竟異步代碼完成顯示代碼執行多久。它顯示屏幕上限經過時間爲0.872s。因此,在所有以前的代碼包括全部異步方法完成後,秒錶會停止。
.......
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();
.......
雖然我跟隨它像上面的代碼段以同樣的方式,我有不同的結果在任一RegisterAsyncTask或等待DoSthAsync()。雖然已用時間顯示在不同的位置,但它們都給我非常短的運行時間約0.010s或10 + ms,並且它認爲秒錶異步功能DoSthAsync()被激發後很短時間停止。事實上,在窗口程序中也有類似的結果,它很快就停止了。
問題的長說明後,我想問一下異步編碼哪種方式更好地控制和代碼模式。在這之間,我怎麼能期望秒錶的結果給我精確的代碼流逝時間。
我也建議你閱讀以下文章由Scott Hanselmann關於這個主題:http://www.hanselman.com/blog/TheMagicOfUsingAsynchronousMethodsInASPNET45PlusAnImportantGotcha.aspx –
@ManuelZelenka我也讀過這篇文章,但它已經沒有提及RegisterAsyncTask和await之間的區別。他只是提到了 「使用async with void並不穩定或可靠,但是您只需要調用Page.RegisterAyncTask - 這不會有任何問題,您將處於一個更加靈活的地方。」這與我提到的裏克的文章是一樣的。他的例子在Page_Load中只有一個動作。 – Donald
是的,我很早以前就在asp.net 2.0中使用RegisterAsyncTask。當它與新的異步等待一起使用時,它感覺有些困難。代碼執行的順序是一個意想不到的。裏克的文章中提到:「與RegisterInyncTask掛鉤的方法將在PreRender之後立即運行」。所以我上面寫的示例意味着DoSthAsync()實際上並不在Page_Load上運行? – Donald