IEnumerable
🐛 Enumerator & Enumerable
Enumerator就是一個「游標(cursor)」,可以指向序列中的某一筆資料,並且知道「怎麼移到下一筆」、「現在這一筆是誰」。
是一個「讀取器」,負責「一筆一筆往前走」,只能唯讀 (read-only)、往前走 (forward-only)
實作的定義是
MoveNext() - 移到下一筆,回傳是否還有資料
Current - 取得目前資料
Reset() - 回到初始狀態(很少用)
介面:IEnumerator、IEnumerator
Enumerable就是一個「序列的抽象描述」,它本身不是游標,但是它可以「生出一個 Enumerator」來幫你走訪它。
是一個「集合的抽象表示」,它不是游標,不會自己動,但它要能生出 Enumerator,讓你真的能走訪它
實作的定義是
GetEnumerator()
介面:IEnumerable、IEnumerable
🐛 IEnumerable & IEnumerator若希望資料集合類別具有走訪能力,需要實作 IEnumerable 以及 IEn ...
Deferred Execution - 延遲的智慧
延遲執行(Deferred Execution)
他是一種耐心的智慧 —— 明明寫下一段 Code,卻不急著執行,彷彿在等待一個更合適的時機 !?
延遲執行(Deferred Execution)
幫助你在被某句話刺到時,第一反應不是想要立刻回嘴、發怒或做出回應。不選擇這種「立即執行」的行為,防止你在關係上造成傷害或是事後後悔
延遲執行(Deferred Execution)
讓我們理解,重大決定前需要沉澱期,轉職、搬家、投資、進入一段關係…… 不適合因為他人的壓力就出發立即執行
而創意與靈感的生成過程,很多時候你以為自己沒有靈感,其實是「狀態機還沒執行」。你已經把表達式建好了,放著沒動,等到靈感來臨時,才會開始真正地「MoveNext()」。
我們不是缺靈感,只是活不夠久,讓它進入可被遍歷的狀態
靈感的延遲執行人生就是一段靈感蒐集箱
1234567891011121314151617181920212223242526public class InspirationCollector : IEnumerab ...
IEnumerable, ICollection, IList and List – Which One To Use?
🐛 IEnumerableIEnumerable 是所有集合的基礎款,ICollection 繼承 IEnumerable,IList 繼承 ICollection,而我們常用的 List 就是 IList 的實作。所以 IEnumerable 相當於阿嬤,要敬老尊賢,或者也可以想像你訂閱了微軟的集合使用基礎方案 : IEnumerable。
基於這個基礎方案我們獲得這些功能:
可以用 foreach 逐筆處理(走訪抽象)。123IEnumerable<string> names = new[] { "Ann", "Bob", "Cindy" };foreach (var n in names) Console.WriteLine(n);
支援延遲執行(LINQ-to-Objects 的 Where/Select/Take)12345var data = Enumerable.Range(1, 1_000_000); // 還沒算var firstFive ...
IEnumerable<T> and IQueryable<T>
IQueryable在 IDE 中寫好的 IQueryable 只是 “查詢狀態”,此時還沒執行資料庫的查詢,因此不會有資料載入記憶體的行為。若指派某些會得到 “明確結果” 的 function,如 Count ()、ToList () 等,此時才會執行 SQL 查詢指令,取得查詢結果。IQueryable 介面會將 Expression 傳遞給 Provider,由 Provider 轉譯成 T-SQL 後,從 DB 中取得資料,得到 “明確結果”
1234567891011// 此時的data是"查詢狀態",資料還未載入記憶體中。IQueryable<Book> Qdata = dbContext.Book;// 在定義變數時加入條件式,也不會將"查詢狀態"載入記憶體中。IQueryable<Book> filterQdata = dbContext.Book.Where(x => x.Id == 1);//下面兩行程式才會執行SQL指令,並將查詢的資料載入記憶體中。var book = filterData.T ...
Yield Return - 本質
🐛 yield return 的核心本質將「一次性完成」的方法,轉換成「逐步產生序列」的狀態機。
傳統方法:輸入 → 計算 → 輸出結果,一次性結束。使用 yield return 方法可以 暫停、保存狀態、按需產生值,直到所有結果都產生完畢。
控制流的「暫停與恢復」使用 yield return,方法不再是從頭到尾一次性執行完畢,而是允許執行到某個點時「暫停」,並記住執行上下文(局部變量、當前位置等),等待下一次繼續執行。
一般方法
123456int[] GenerateNumbers(){ return new int[] { 1, 2, 3 };}
使用 yield return
12345678IEnumerable<int> GenerateNumbers(){ yield return 1; yield return 2; yield return 3;}
執行過程像這樣:
第一次 MoveNext() → 跑到 yield return 1,暫停,回傳 1第二次 M ...
Yield Return - 實驗
🐛 IEnumerable + yield 的運作機制詳解
一般集合的回傳方式123456789101112131415161718192021222324252627282930313233void Main(){ var store = new DemoStore(); var productList = store.GetProducts(); foreach (var product in productList) { $"{product.Id},{product.Name}".Dump(); }}public class DemoStore{ public List<Product> GetProducts() { List<Product> result = new List<Product>(); for (int i = 0; ...
Asynchronous Programming - 第六章:時間碎片裡的員工們-2
共享資源沒有被妥善同步處理Race Condition(競態條件)Deadlock(死鎖)Starvation(飢餓)Priority Inversion(優先級反轉)Multi-threading 做法Multi-processingAPI Web ServerChrome 使用 Multi-Process 架構IDE共享資源是什麼?
一筆資料(例如某筆訂單、座位狀態)
一段記憶體(像共用的快取陣列)
一個硬體裝置(例如印表機、檔案寫入)
一個全域變數或物件
甚至是「系統的鎖資源本身」
當系統有了多個 Thread,一切看似井然有序、效率飛快,但只要一不小心,就會變成一場混亂的現場。這些混亂,我們統稱為同步問題(Synchronization Problems)。這些問題源自一個核心事實,多個執行緒試圖同時存取同一份共享資源,卻沒有適當協調。結果就像幾個員工搶著用一台影印機,可能導致不是印出錯內容、就是永遠卡在佇列。
同步問題常見的四大類型如下,我們以訂票系統來說明
執行緒 1 和執行緒 2 同時查詢「座位 A1 是否可訂」,兩者皆發現「尚未被預訂」,於是幾乎同時發出訂位請求。 ...
Asynchronous Programming - 第六章:時間碎片裡的員工們
huanlintalk莫力全 Kyle MoProgram,Process,Thread青耀隨筆談
Program、Process、Thread當世界還只能一條路餐廳開多間了,但廚師還是只有一個員工來了—— Thread 的誕生換人上場的代價:執行緒的切換成本CPU 的角色輪替當 Thread 遇上外來者:非託管 DLL 的插手summary想像你是一位準備開店的廚師,桌上攤開一本厚重的菜譜,這就是你的 Program(程式碼集合)。它記錄了每道菜的做法、調味的比例、上菜的順序……但這些指示仍停留在紙上,尚未進入現實。它像是還未走進世界的夢,只存在於設計之中。
當你真正開張營業、招呼客人,這份菜譜就被實體化成了一間 Process(處理程序)一間運作中的餐廳。這間餐廳開始佔據空間(記憶體)、使用瓦斯爐(CPU)、冰箱(硬碟),並啟動了你的夢想。每一間正在運作的餐廳,都是一個獨立的 Process,就像你電腦上同時開著 Word、Chrome 和 Spotify,一家店煮咖哩、一家店沖咖啡,彼此不會互相干擾。。
但餐廳開起來只是第一步,真正讓整個流程流動的,是餐廳裡的「人」—— 這些人 ...
.NET CORE 環境變數
將 APIKey 存進環境變數參考 : https://blog.darkthread.net/blog/secure-apikey-for-console-app/
1234567891011121314151617181920212223242526byte[] additionalEntropy = { 9, 8, 7, 6, 5 };Func<string, string> GetSecureEnvVar = (varName) => { var val = Environment.GetEnvironmentVariable(varName, EnvironmentVariableTarget.User); if (!string.IsNullOrEmpty(val)) { try { val = Encoding.UTF8.GetString( ProtectedData.Unprotect(Convert.F ...
Asynchronous Programming - 第五章:錯誤等待的死鎖之吻
love為什麼 .Result 有時會讓整個程式卡住ASP.NET Core 不再死鎖如果我用 await 而不是 .Resultsummary
他們曾經相愛,也曾經深信,只要彼此都願意等,愛就會回來
她把訊息輸入對話框,卻沒有按下傳送,想等他主動說第一句話。她想:「他如果真的在乎,就會找我。」他打開視窗看了又看,也沒傳訊息,心想:「她如果還有感覺,就會先聯絡我。」
它們每天打開彼此的聊天室又關上,不是沒有思念,而是不願先伸出手。怕輸、怕低頭、怕被拒絕,在各自的世界靜靜地等,畫了一個誰也跨不過的等待邊界,兩個 .Result() 卡在彼此門前,沒有人願意給對方 await 的空間
async deadlock
await 與 Task.Result/Task.Wait () 的 Deadlock 問題
在 ASP.NET 舊版框架中,若在同步方法中呼叫非同步方法
1var result = GetDataAsync().Result;
可能會遇到一個非常棘手的問題:Deadlock
事情是這樣發生的
主執行緒呼叫 .Result,進入「同步等待」狀態,卡住不動
GetDa ...








