日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET Core Web 应用程序系列(四)- ASP.NET Core 异步编程之async await

發布時間:2023/12/13 asp.net 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Core Web 应用程序系列(四)- ASP.NET Core 异步编程之async await 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

PS:異步編程的本質就是新開任務線程來處理。

約定:異步的方法名均以Async結尾。

實際上呢,異步編程就是通過Task.Run()來實現的。

了解線程的人都知道,新開一個線程來處理事務這個很常見,但是在以往是沒辦法接收線程里面返回的值的。所以這時候就該await出場了,await從字面意思不難理解,就是等待的意思。

執行await的方法必須是async修飾的,并且是Task的類型。 異步執行后,返回的信息存儲在result屬性中。但并非主進程就會卡在await行的代碼上,執行到await方法之后主線程繼續往下執行,無需等待新的線程執行完再繼續。只有當需要用到新線程返回的result結果時,此時主進程才會等待新線程執行完并返回內容。也就是說,若無需用到新線程返回的結果,那么主進程不會等待。

async和await呢,返回類型就3種:void、Task、Task<TResult>。

1、void

如果在觸發后,你懶得管,請使用 void。

void返回類型主要用在事件處理程序中,一種稱為“fire and forget”(觸發并忘記)的活動的方法。除了它之外,我們都應該盡可能是用Task,作為我們異步方法的返回值。

返回void,意味著不能await該異步方法,即可能出現線程阻塞,并且也無法獲取exception拋出的異常,通常這些異常會導致我們的程序失敗,如果你使用的是Task和Task<TResult>,catch到的異常會包裝在屬性里面,調用方法就可以從中獲取異常信息,并選擇正確的處理方式。

2、Task

你如果只是想知道執行的狀態,而不需要一個具體的返回結果時,請使用Task。
與void對比呢,Task可以使用await進行等待新線程執行完畢。而void不需要等待。

3、Task<TResult>?

當你添加async關鍵字后,需要返回一個將用于后續操作的對象,請使用Task<TResult>。

主要有兩種方式獲取結果值,一個是使用Result屬性,一個是使用await。他們的區別在于:如果你使用的是Result,它帶有阻塞性,即在任務完成之前進行訪問讀取它,當前處于活動狀態的線程都會出現阻塞的情形,一直到結果值可用。所以,在絕大多數情況下,除非你有絕對的理由告訴自己,否則都應該使用await,而不是屬性Result來讀取結果值。

?

接下來我們來看個例子,在上一章的基礎上我們添加異步的方法。

首先是倉儲層接口:

using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks;using TianYa.DotNetShare.Model;namespace TianYa.DotNetShare.Repository {/// <summary>/// 學生類倉儲層接口/// </summary>public interface IStudentRepository{/// <summary>/// 根據學號獲取學生信息/// </summary>/// <param name="stuNo">學號</param>/// <returns>學生信息</returns>Student GetStuInfo(string stuNo);/// <summary>/// 根據學號獲取學生信息(異步)/// </summary>/// <param name="stuNo">學號</param>/// <returns>學生信息</returns>Task<Student> GetStuInfoAsync(string stuNo);} }

接著是倉儲層實現:

using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks;using TianYa.DotNetShare.Model;namespace TianYa.DotNetShare.Repository.Impl {/// <summary>/// 學生類倉儲層/// </summary>public class StudentRepository : IStudentRepository{/// <summary>/// 根據學號獲取學生信息/// </summary>/// <param name="stuNo">學號</param>/// <returns>學生信息</returns>public Student GetStuInfo(string stuNo){//數據訪問邏輯,此處為了演示就簡單些var student = new Student();switch (stuNo){case "10000":student = new Student() { StuNo = "10000", Name = "張三", Sex = "", Age = 20 };break;case "10001":student = new Student() { StuNo = "10001", Name = "錢七七", Sex = "", Age = 18 };break;case "10002":student = new Student() { StuNo = "10002", Name = "李四", Sex = "", Age = 21 };break;default:student = new Student() { StuNo = "10003", Name = "王五", Sex = "", Age = 25 };break;}return student;}/// <summary>/// 根據學號獲取學生信息(異步)/// </summary>/// <param name="stuNo">學號</param>/// <returns>學生信息</returns>public virtual async Task<Student> GetStuInfoAsync(string stuNo){return await Task.Run(() => this.GetStuInfo(stuNo));}} }

然后是服務層接口:

using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks;using TianYa.DotNetShare.Model;namespace TianYa.DotNetShare.Service {/// <summary>/// 學生類服務層接口/// </summary>public interface IStudentService{/// <summary>/// 根據學號獲取學生信息/// </summary>/// <param name="stuNo">學號</param>/// <returns>學生信息</returns>Student GetStuInfo(string stuNo);/// <summary>/// 根據學號獲取學生信息(異步)/// </summary>/// <param name="stuNo">學號</param>/// <returns>學生信息</returns>Task<Student> GetStuInfoAsync(string stuNo);} }

再接著是服務層實現:

using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks;using TianYa.DotNetShare.Model; using TianYa.DotNetShare.Repository;namespace TianYa.DotNetShare.Service.Impl {/// <summary>/// 學生類服務層/// </summary>public class StudentService : IStudentService{/// <summary>/// 定義倉儲層學生抽象類對象/// </summary>protected IStudentRepository StuRepository;/// <summary>/// 空構造函數/// </summary>public StudentService() { }/// <summary>/// 構造函數/// </summary>/// <param name="stuRepository">倉儲層學生抽象類對象</param>public StudentService(IStudentRepository stuRepository){this.StuRepository = stuRepository;}/// <summary>/// 根據學號獲取學生信息/// </summary>/// <param name="stuNo">學號</param>/// <returns>學生信息</returns>public Student GetStuInfo(string stuNo){var stu = StuRepository.GetStuInfo(stuNo);return stu;}/// <summary>/// 根據學號獲取學生信息(異步)/// </summary>/// <param name="stuNo">學號</param>/// <returns>學生信息</returns>public virtual async Task<Student> GetStuInfoAsync(string stuNo){return await StuRepository.GetStuInfoAsync(stuNo);}} }

最后進行控制器中的調用:

using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using TianYa.DotNetShare.CoreAutofacDemo.Models;using TianYa.DotNetShare.Service; using TianYa.DotNetShare.Repository; using TianYa.DotNetShare.Repository.Impl;namespace TianYa.DotNetShare.CoreAutofacDemo.Controllers {public class HomeController : Controller{/// <summary>/// 定義倉儲層學生抽象類對象/// </summary>private IStudentRepository _stuRepository;/// <summary>/// 定義服務層學生抽象類對象/// </summary>private IStudentService _stuService;/// <summary>/// 定義服務層學生抽象類對象/// 屬性注入:訪問修飾符必須為public,否則會注入失敗。/// </summary>public IStudentService StuService { get; set; }/// <summary>/// 定義倉儲層學生實現類對象/// 屬性注入:訪問修飾符必須為public,否則會注入失敗。/// </summary>public StudentRepository StuRepository { get; set; }/// <summary>/// 通過構造函數進行注入/// 注意:參數是抽象類,而非實現類,因為已經在Startup.cs中將實現類映射給了抽象類/// </summary>/// <param name="stuRepository">倉儲層學生抽象類對象</param>/// <param name="stuService">服務層學生抽象類對象</param>public HomeController(IStudentRepository stuRepository, IStudentService stuService){this._stuRepository = stuRepository;this._stuService = stuService;}public IActionResult Index(){var stu1 = StuRepository.GetStuInfo("10000");var stu2 = StuService.GetStuInfo("10001");var stu3 = _stuService.GetStuInfo("10002");var stu4 = _stuRepository.GetStuInfo("1003");string msg = $"學號:10000,姓名:{stu1.Name},性別:{stu1.Sex},年齡:{stu1.Age}<br />";msg += $"學號:10001,姓名:{stu2.Name},性別:{stu2.Sex},年齡:{stu2.Age}<br/>";msg += $"學號:10002,姓名:{stu3.Name},性別:{stu3.Sex},年齡:{stu3.Age}<br/>";msg += $"學號:10003,姓名:{stu4.Name},性別:{stu4.Sex},年齡:{stu4.Age}<br/>";return Content(msg, "text/html", System.Text.Encoding.UTF8);}public async Task<IActionResult> Privacy(){var stu = await _stuService.GetStuInfoAsync("10000");return Json(stu);}[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]public IActionResult Error(){return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });}} }

至此完成處理,我們來訪問一下/home/privacy,看看是否正常

可以看出是正常的

下面我們演示一下什么時候需要用到result屬性:

//用了await則不需要Result屬性 public async Task<IActionResult> Privacy() {var stu = await _stuService.GetStuInfoAsync("10000");return Json(stu); } //沒有用await則需要Result屬性 public async Task<IActionResult> Privacy() {var stu = _stuService.GetStuInfoAsync("10000").Result;return Json(stu); }

至此我們的異步編程就講解完了。

總結:

1、盡量優先使用Task<TResult>和Task作為異步方法的返回類型。

2、如果用了await則方法必須使用async來修飾,并且是Task的類型。

demo源碼:

鏈接:https://pan.baidu.com/s/1Wb0Mebm-nh9YFOaYNLwO-g 提取碼:1ayv

?

參考博文:https://www.cnblogs.com/fei686868/p/9637310.html

版權聲明:如有雷同純屬巧合,如有侵權請及時聯系本人修改,謝謝!!!

轉載于:https://www.cnblogs.com/xyh9039/p/11391507.html

總結

以上是生活随笔為你收集整理的ASP.NET Core Web 应用程序系列(四)- ASP.NET Core 异步编程之async await的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。