[上課筆記] C# 開發實戰:非同步程式開發技巧

C# 開發實戰:非同步程式開發技巧

will 保哥的實體課程
講義 188 張 
範例專案 39 個
上課日期 2019-12-03 ,17 兩天
心得 :  課程中重視理解觀念 不停的用問答的方式 建立對的觀念
非同步真的非常難以理解 最大的收穫 async await task 用起來不再似懂非懂
多開執行續不見得跑比較快是要看有沒有需要
要注意執行緒安全 如何偵錯 與 處理例外
 

觀念
非同步 是並行計算 也就是 還是同一時間只能處理一件事情 但是是輪流處理 
ex  有A B兩個工作 先處理A到15% 切到B處理到30%在切回A處理到60% 在切換B處理到70% 這樣

補充 平行計算 就是同時處理多個工作
ex  有A B兩個工作 同時開始處理兩個工作到結束

非同步主要可以讓 需要處理較久的工作 開一個執行緒去處理 讓原本的執行緒服務別的工作
桌面應用程式 - 讓UI可以正常運作 需要長時間工作的運算 開一個執行緒去處理
網站應用程式 - 讓同時間服務網站的人數 可以提高 但是每個人開網頁的時間並不會變快

需要處理比較久的工作 可以分成 CPU Bound 跟 I/0 Bound

電腦的資源來說 CPU資源是最珍貴的 你的電腦有幾個核心 就表示可以同時處理幾個執行緒
EX 你是物理雙核CPU 軟體模擬四核 這樣作業系統可以同時跑的執行緒 就是 4個 

非同步主要目的
    - 榨乾CPU (自然更有效率)
    - 更有效率使用CPU

特色
非同步的特色就是 "我做完後將會回來"
並不是無腦將全部的方法都改用非同步 只有執行需要50ms以上的 才建議改
(因為切換執行緒是需要代價的)
非同步程式 沒有經驗的開發者 通常你寫的跟你想的執行順序是不一樣的

等待有分成 
   - block thread - 執行緒等待中 不做任何事
   - non block thread - 原本執行緒 開一個新執行緒去做事 將原本執行緒歸還

thread
自己 new thread 需要控管例外 要不然 發生例外時 程式直接結束 沒有任何錯誤訊息
thread.Join() 是 block thread
thread 執行的先後順序 是作業系統決定 不是code的先後順序決定
EX 先執行thread1.Start() 後執行thread2.Start() 不保證thread1.Start會先執行

執行緒安全 - Thread Safe
在多個執行緒同時工作下 所得到的結束都是相同 就是 執行緒安全
ex 你開 兩個thread 對同一個變數int 做+1 結果每次都不相同 而且會比預期的少 這就是 沒有  Thread Safe
最簡單的解法 就是 加上 Lock 最簡單 但是效能最差 (迷之音 但是調快有人感覺得出來嗎 )

用Lock去將多執行緒的結果都是相同的手段 叫做 同步化 (Synchronization)

其實.NET Framework 基礎類別庫 都是沒有 執行緒安全 
EX : List , Dictionary , int

NET4.0 開始有Task
  - Task 就是封裝 thread , 預設用 thread pool
  - 初始thread 數量就是你的軟體核心數 若1秒處理不完才會再加一條thread ,再一秒處理不完 再開一條 以此類推
( 這裡 解了之前使用時 遇到的一大謎題 )

Task 物件
 - 回傳Task 表示沒有回傳值  task 本身是紀錄狀態 (就是 void)
 - 回傳Task<int> 表示回傳值是int 
 - task.Result 是  block thread 
 - task.Wait() 是  block thread
 - task.WaitAll() / task.WaitAny()   是 block thread

Task 的 Status屬性
- IsCompleted
- IsCanceled
- IsFaulted (例外發生)

Task內要不要開Task是要看 還有沒有超過50ms的方法 多開task 不會比較快

awite 只會要由回傳 task 不是要求 asyc 方法

真正非同步 就是 真的去開新 執行續

不加 標示 async 就無法更有效率地等待

.result 或 .wait 才有機會 dead lock

只有用上async await 才有機會 dead lock

ConfigureAwait(false) 表示 不需要原始thead 回來接續處理, 可以讓新的執行續接續處理
會失去SynchronizationContext
https://www.youtube.com/watch?v=avhLfcgIwbg

AsyncAwaitBestPractices  - SafeFireAndForget
https://github.com/brminnick/AsyncAwaitBestPractices

補充教材
C# 開發實戰:非同步程式開發技巧 - 延伸學習資源

如果內容有誤請多鞭策謝謝