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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

Asp.Net Core 轻松学-经常使用异步的你,可能需要看看这个文章

發(fā)布時(shí)間:2023/12/4 asp.net 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Asp.Net Core 轻松学-经常使用异步的你,可能需要看看这个文章 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

事情的起因是由于一段簡(jiǎn)單的數(shù)據(jù)庫(kù)連接代碼引起,這段代碼從語(yǔ)法上看,是沒(méi)有任何問(wèn)題;但是就是莫名其妙的報(bào)錯(cuò)了,這段代碼極其簡(jiǎn)單,就是打開(kāi)數(shù)據(jù)庫(kù)連接,讀取一條記錄,然后立即更新到數(shù)據(jù)庫(kù)中。但是,慘痛的事實(shí)證明,老司機(jī)也是會(huì)翻車(chē)的。

1. 異常的發(fā)生來(lái)得太突然


1.1 引起不舒適的代碼片段

這是一段不太標(biāo)準(zhǔn)的異步接口,可能你也這么寫(xiě)過(guò), 從結(jié)構(gòu)和語(yǔ)法上看,這段代碼沒(méi)有任何問(wèn)題,而且正常情況下,它還能執(zhí)行成功


1.2 報(bào)錯(cuò)信息

從報(bào)錯(cuò)信息中可以看出,數(shù)據(jù)庫(kù)上下文對(duì)象被銷(xiāo)毀了,是在什么時(shí)候銷(xiāo)毀的呢,通過(guò)跟蹤程序,了解到,是在 this.context.Update(topic); ,調(diào)用 Update 后執(zhí)行了 DbContext.Dispose(),為了證明這點(diǎn),我們重寫(xiě) DbContext.Dispose() 方法,并簡(jiǎn)單的輸出一句話(huà)


1.3 重寫(xiě) DbContext.Dispose()

1.4 再次執(zhí)行程序,查看結(jié)果

通過(guò)輸出結(jié)果紅色方框處可以看到,確實(shí)是在執(zhí)行了 Update 以后執(zhí)行了 Dispose 方法,關(guān)于這點(diǎn),如果我們使用了同步方法,先 Update 再 SaveChanges ,這是沒(méi)有任何問(wèn)題的,理論上說(shuō),EFCore 中啟用了 AutoDetectChangesEnabled,我們?cè)谏厦娴拇a中其實(shí)無(wú)需調(diào)用 Update,直接 SaveChangesAsync 即可,也不會(huì)拋出異常,同理,如果是在同步方法中,先執(zhí)行 Update 再 SaveChanges ,也是沒(méi)有任何問(wèn)題的


1.5 同步 SaveChanges

  • 輸出結(jié)果

從輸出結(jié)果可知,先執(zhí)行了 Update,然后執(zhí)行了 SaveChanges 輸出 affrows,最后執(zhí)行了 Dispose 方法

2. 問(wèn)題所在

那到底是什么問(wèn)題引起了程序執(zhí)行的不確定性呢,答案就是 async/await,我們先來(lái)嘗試改進(jìn)一下最初的代碼


2.1 改進(jìn)后的代碼

細(xì)心的你已經(jīng)發(fā)現(xiàn),這段代碼和 1.1 之中的沒(méi)有太多的不同,無(wú)非是增加了一些跟蹤信息,其中,最關(guān)鍵的是:增加了返回值為:Task ,替換了 void


2.2 再次執(zhí)行修正的程序

輸出結(jié)果和 1.5 中的同步方法完全相同,至此,問(wèn)題解決

3. 問(wèn)題的解決方案


3.1 問(wèn)題分析

為什么會(huì)發(fā)生這種問(wèn)題呢,原因就是因?yàn)槭褂昧水惒椒椒?async/await 時(shí),當(dāng)沒(méi)有值需要返回時(shí),使用了 void 造成的,正確的做法是如果沒(méi)有返回值,則返回 Task,如果有返回值,則使用 Task?;當(dāng)一個(gè)異步方法內(nèi)部沒(méi)有返回 Task 的時(shí)候,基于任務(wù)的異步模式(TAP)并不知道異步任務(wù)的狀態(tài),當(dāng) this.context.Update 執(zhí)行完成后,發(fā)現(xiàn)掛載在內(nèi)存中的連接已經(jīng)沒(méi)有使用,就執(zhí)行了回收;實(shí)際上,此時(shí)程序還沒(méi)有執(zhí)行完成,但是 TAP 并不知道,所以它不會(huì)去阻止這個(gè)回收的過(guò)程(使用標(biāo)記),所以 async/await 應(yīng)該成對(duì)出現(xiàn),并且應(yīng)該始終返回 Task 或者 Task,以確保 TAP 能夠?qū)⑸舷挛倪M(jìn)行正確的掛載,否則,當(dāng)異常發(fā)生時(shí),TAP 無(wú)非將異常信息掛載到相應(yīng)的 Task 上,亦無(wú)法跟蹤其執(zhí)行狀態(tài)等信息


3.2 解決方案

請(qǐng)牢記下面的鐵律

  • 3.2.1 在 EFCore 中,應(yīng)當(dāng)始終發(fā)揮 AutoDetectChangesEnabled 的特性,不要再更新實(shí)體的時(shí)候去調(diào)用 Update 方法

  • 3.2.2 使用 async/await 修飾方法時(shí),應(yīng)該始終返回 Task 或者 Task

  • 適當(dāng)?shù)氖褂猛椒椒?#xff0c;可避免異步踩坑


演示代碼下載

https://github.com/lianggx/EasyAspNetCoreDemo/tree/master/Ron.TaskThird

原文地址:https://www.cnblogs.com/viter/p/10271212.html


.NET社區(qū)新聞,深度好文,歡迎訪(fǎng)問(wèn)公眾號(hào)文章匯總 http://www.csharpkit.com


總結(jié)

以上是生活随笔為你收集整理的Asp.Net Core 轻松学-经常使用异步的你,可能需要看看这个文章的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。