並行任務(Task)以及基於Task的異步編程(asynchronously)在.NET Framework早已使用多年,而在微軟新推出的.NET Core 平臺下也有相同功能的實現,本文將經過.NET Core WebAPI,介紹使用Task.result的同步編程以及使用await的異步編程模型。html
Result方法能夠返回Task執行後的結果,以下代碼:web
[HttpGet] public static async Task<JObject> GetJsonAsync(Uri uri) { using (var client = new HttpClient()) { var jsonString = await client.GetStringAsync(uri); return JObject.Parse(jsonString); } } public class MyController : ApiController { public string Get() { var jsonTask = GetJsonAsync(...); return jsonTask.Result.ToString(); } }
可是若是在ASP.NET Core的webapi中使用result方法來獲取task輸出值,會形成當前API線程阻塞等待到task執行完成後再繼續進行。能夠經過下面代碼來證實,get方法有一個線程,調用一個新線程執行task(taskcaller),在執行task時候因爲須要等待task的執行結果,此時get方法的執行線程等待中,直到result結果輸出,此線程繼續完成方法。編程
[HttpGet] public string Get() { var info = string.Format("api執行線程:{0}", Thread.CurrentThread.ManagedThreadId); var infoTask = TaskCaller().Result; var infoTaskFinished = string.Format("api執行線程(task調用完成後):{0}", Thread.CurrentThread.ManagedThreadId); return string.Format("{0},{1},{2}", info, infoTask, infoTaskFinished); } private async Task<string> TaskCaller() { await Task.Delay(500); return string.Format("task 執行線程:{0}", Thread.CurrentThread.ManagedThreadId); }
代碼執行流程json
輸出結果以下api
若是使用await,在調用 await taskcall() 時不會阻塞get主方法線程,主方法線程會被釋放,新的線程執行完成task後繼續執行await後的代碼減小線程切換開銷,而以前的線程則空閒了。異步
[HttpGet] public async Task<string> Get() { var info = string.Format("api執行線程:{0}", Thread.CurrentThread.ManagedThreadId); var infoTask = await TaskCaller(); var infoTaskFinished = string.Format("api執行線程(task調用完成後):{0}", Thread.CurrentThread.ManagedThreadId); return string.Format("{0},{1},{2}", info, infoTask, infoTaskFinished); } private async Task<string> TaskCaller() { await Task.Delay(500); return string.Format("task 執行線程:{0}", Thread.CurrentThread.ManagedThreadId); }
代碼執行流程async
輸出結果以下異步編程
Task.result 與 await關鍵字 具備相似的功能能夠獲取到任務的返回值,可是本質上Task.result會讓外層函數執行線程阻塞直到任務執行完成,而使用await關鍵字外層函數線程則不會阻塞,而是經過任務執行線程來執行await後的代碼。函數
做者:帥蟲哥 出處: http://www.cnblogs.com/vipyoumay/p/5663950.html線程