.Net Core WebAPI 基於Task的同步&異步編程快速入門


並行任務(Task)以及基於Task的異步編程(asynchronously)在.NET Framework早已使用多年,而在微軟新推出的.NET Core 平台下也有相同功能的實現,本文將通過.NET Core WebAPI,介紹使用Task.result的同步編程以及使用await的異步編程模型。

Task.Result

Result方法可以返回Task執行后的結果,如下代碼:

[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);
}

代碼執行流程

執行原理

輸出結果如下

result

async & await

如果使用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);
}

代碼執行流程

執行流程

輸出結果如下

await

總結

Task.result 與 await關鍵字 具有類似的功能可以獲取到任務的返回值,但是本質上Task.result會讓外層函數執行線程阻塞直到任務執行完成,而使用await關鍵字外層函數線程則不會阻塞,而是通過任務執行線程來執行await后的代碼。


作者:帥蟲哥 出處: http://www.cnblogs.com/vipyoumay/p/5663950.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM