Asynchronous Programming - 第三章:非同步中的等待藝術
全自動咖啡機Task.Run(...) 的本質CPU-bound vs I/O-boundsummary小遙家裡有一台很貴的全自動咖啡機。只要放入咖啡豆,按下按鈕,五分鐘後,一杯完美的拿鐵便會端坐在托盤上,溫度與比例都恰到好處
但她還是習慣站在一旁等
她不相信機器;在咖啡流出前的幾十秒,她總會打開上蓋,觀察豆槽有沒有卡住,再輕拍一下;聽見磨豆的聲音時,也會試著微調參數、瞄一下壓力表。她甚至曾試著在機器運作時,手動幫忙攪拌牛奶。直到有一天,她打翻了一杯還沒加糖的咖啡,才驚覺:其實什麼都不做,才是真的在等那杯咖啡完成
有些事情,本質上就像 I/O-bound 的任務,對方的成長、一段關係的發酵、時機的成熟、情緒的消化,它們需要的是時間與環境,不是你額外派一個「焦慮的自己」去乾等
Task.Run 的本質不是「非同步」,而是把你原本會卡住目前執行緒的同步工作,轉交給 Thread Pool 的背景執行緒去扛,讓現在這條執行緒先活下來
12345678public static Task Run(Action action){ return Task.Fac ...
組合的力量與設計哲學
在上一篇文章中,我們看到繼承帶來的限制與設計陷阱。本篇將把鏡頭轉向另一個更自由、更靈活的設計哲學 —— 組合(Composition)。
組合就像是把系統拆解成可重組的積木,每個模組只負責一個任務,清晰、精準、可插拔,讓程式不僅易於擴充,也更能回應未來的變化。
🌸 組合怎麼解決問題?用組合代替繼承,解決行為歧義(Ambiguity of Behavior)讓戰鬥法師「擁有」戰士和法師的能力,而不是「繼承」它們。
12345678910public class Battlemage{ private Warrior _warrior = new Warrior(); private Mage _mage = new Mage(); public void MeleeAttack() => _warrior.Attack(); public void CastSpell() => _mage.CastSpell();}
用 Interface 來分離行為,避免多繼承,解決屬性重複(Duplicate State)讓 Warrio ...
從克德族說起:繼承為何讓人生卡關?
好久好久以前,有兩個著名的家族——
克德族,是一個信奉血統主義的家族。他們深信純正血脈的力量,嚴格遵循世代傳承的家族傳統,認為唯有優良基因的延續,才能孕育出最優秀的後代。起初,這種方式的確造就了不少傑出人才。克德家的子女大多具備出色的音感,未來幾乎都走上了音樂的道路。
但隨著時間流逝,問題逐漸浮現。某一天,家族中一位孩子心懷成為機械技師的夢想,卻發現家族的傳統成了束縛。他無法脫離音樂的陰影,也難以獲得從事機械所需的技能,陷入深深的痛苦與迷惘。
海的另一端,是萊雅族。這是一個秉持開放思想的家族。他們相信卓越不僅來自血統,更來自個人的選擇與學習。他們鼓勵每位成員自由探索,組合各種不同的技能與知識。
這樣的理念帶來了極大的彈性。萊雅族的子女可以依興趣學習,不論是音樂、機械或其他領域皆不受限制。他們甚至可以同時成為音樂家與技師。
然而,自由也帶來困惑。因選擇過多,部分成員在成長過程中感到迷惘,沒有明確的方向。不僅如此,因為每個人都走著截然不同的路,外人甚至難以辨別他們是否屬於同一族群。
克德族的困境,就像物件導向中的繼承(Inheritance)。子類別(Subclass)往往難以擺脫父 ...
(NEW)EFCORE效能
https://blog.darkthread.net/blog/ef-core-test-with-in-memory-db單純 CRUD 用 EF (或自製 ORM) 享受強型別保護及不沾 SQL 的清爽,至於複雜查詢、批次更新刪除,則回歸自己寫 SQL 以確保執行效能。
案例 1. 叫用 csp 時
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 public virtual async Task<List<csp_GetPromotionEngineSpecialPriceDataResult>> csp_GetPromotionEngineSpecialPriceDataAsync(string queryType, string salePageIds, string skuIds, string pro ...
(NEW)EFCORE效能
https://blog.darkthread.net/blog/prevent-aspnet-session-timeout/
AutoMapper
organic and gluten-free ?
最近,對研發工具有些興趣。在眾多工具中,AutoMapper 作為研究對象。儘管我對它的了解還停留在一知半解的階段,但我決定以此為切入點,探索「使用工具」這個主題背後的含義。
通過研究 AutoMapper,我開始思考:一個好的工具應該具備哪些特質?它如何影響我們的工作方式和思維模式?在軟體開發中,我們應該如何權衡使用現成工具和自行開發之間的利弊?
自訂轉換邏輯例如在 DB 我們有這個 Model
12345678910111213public class CountryProfile{ public long CountryProfile_Id { get; set; } public string CountryProfile_Code { get; set; } public string CountryProfile_Name { get; set; } public string CountryProfile_EnglishName { get ...
Stripe
The Payment Intents APIPayment Intents API 是 Stripe 提供的一個用於處理複雜支付流程的工具。思考:為什麼需要一個專門的 API 來處理支付流程?傳統的支付處理方式有什麼局限性?
主要功能:
處理變化的支付狀態追蹤整個支付生命週期在需要時觸發額外的認證步驟
思考:這些功能如何提高支付流程的可靠性和安全性?
優勢:
自動處理認證避免重複收費解決冪等性問題支持強客戶認證(SCA)
思考:這些優勢如何簡化開發流程?它們如何影響用戶體驗?
應用場景:
每個 PaymentIntent 通常對應一個購物車或客戶會話
思考:這種對應關係如何幫助管理複雜的電子商務場景?
123456curl https://api.stripe.com/v1/payment_intents \ -u "sk_test_51EzmjGHfnYtXGyLlBsqBOKEDpX4DL7sHijDHAtwmoHDZBpiRrCltklTNhRCKrUSGjUtAJuxOZ6GAoG6PX2aq0TYH00w2QKSIR4:" \ -d amount=1 ...
HttpContext 失效時,我們還能說什麼
那是一個午後,城市被陽光輕輕包裹著。我走過熟悉的街口,沒有目的地,只是順著記憶走。
咖啡廳的窗戶閃著熟悉的光,我下意識地望進去 —— 她,就坐在靠窗的位置。那個多年不見的身影,仍舊筆挺,肩上落著光,就像記憶裡的那樣。
我愣了一下,彷彿穿越了幾年的時間。當正要推開門的時候,門內走來一名男子,笑著坐在她對面,手中拿著兩杯咖啡。
她抬頭接過咖啡,對他微笑,那笑容熟悉卻已不再屬於你。
片刻後,一個小男孩蹦蹦跳跳地衝進店裡,喊著「爸爸!」男人張開手臂將他抱起,她則伸手輕拍孩子的頭髮。
你靜靜地站在門外,手輕輕從門把上放下。你沒有走進去,也沒有發出聲音。因為你知道,那個 context,早已不在了。
你轉身離開,步伐輕而穩,那封從未送出的請求,就此作廢。
愛必須在對的 context 中發送。
...
Data Validation
[ApiController]Data AnnotationsFluentValidationsummary
[ApiController] 這個 Attribute 會幫 ASP.NET Core Web API 預先接手一部分「參數綁定」和「資料驗證」的工作,讓 Controller 更像在專心處理業務邏輯,而不是一直重複寫防呆判斷。
進來的 Request 先做參數來源判斷,ASP.NET Core 會先看 Action 參數的型別,推測資料應該從哪裡來
複雜型別,通常從 Request Body 取值
IFormFile 或 IFormFileCollection,通常從 Form Data 取值,上傳檔案時,前端通常會送 multipart/form-data。[ApiController] 看到參數型別是 IFormFile 或 IFormFileCollection,就知道這不是一般 JSON,而是表單資料
簡單型別或其他一般參數,通常從 Query String 取值
框架自動做 Model Binding,也就是把 HTTP Request 裡的 ...









