並行編程實戰 — 基於 C# 8 和 .NET Core 3 Hands-On Parallel Programming with C# 8 and .NET Core 3

Tanwar, Shakti 馬琳琳 譯

  • 並行編程實戰 — 基於 C# 8 和 .NET Core 3-preview-1
  • 並行編程實戰 — 基於 C# 8 和 .NET Core 3-preview-2
  • 並行編程實戰 — 基於 C# 8 和 .NET Core 3-preview-3
並行編程實戰 — 基於 C# 8 和 .NET Core 3-preview-1

買這商品的人也買了...

商品描述

《並行編程實戰:基於C# 8和.NET Core 3》詳細闡述了與並行編程相關的基本解決方案,主要包括並行編程簡介、任務並行性、實現數據並行、使用PLINQ、同步原語、使用並發集合、通過延遲初始化提高性能、異步編程詳解、基於任務的異步編程基礎、使用Visual Studio調試任務、編寫並行和異步代碼的單元測試用例、ASP.NET Core中的IIS和Kestrel、並行編程中的模式、分佈式存儲管理等內容。此外,本書還提供了相應的示例、代碼,以幫助讀者進一步理解相關方案的實現過程。 《並行編程實戰: 基於C# 8和.NET Core 3》適合作為高等院校電腦及相關專業的教材和教學參考書,也可作為相關開發人員的自學讀物和參考手冊。

作者簡介

沙克蒂·坦沃是Techpro Compsoft Pvt Ltd(一家全球信息技術諮詢提供商)的首席執行官。
他是一名技術推廣人員和軟件架構師,在軟件開發和企業培訓方面擁有超過15年的經驗。 
Shakti是一名Microsoft認證培訓師,並且一直與Microsoft合作在中東地區開展培訓。
他的專業領域包括.NET、Azure機器學習、人工智能、純函數式編程的應用和並行計算等。

目錄大綱

目錄
第1篇  線程、多任務和異步基礎
第1章  並行編程簡介 3
1.1  技術要求 3
1.2  為多核計算做準備 4
1.2.1  進程 4
1.2.2  硬件和應用程序的性能 4
1.2.3  多任務 4
1.2.4  超線程 5
1.2.5  Flynn分類法 6
1.2.6  線程 7
1.2.7  線程類型 7
1.2.8  線程單元狀態 7
1.2.9  多線程 10
1.2.10  Thread類 12
1.2.11  使用Thread類的優缺點 16
1.2.12  ThreadPool類 17
1.2.13  使用ThreadPool的優缺點 19
1.2.14  BackgroundWorker 20
1.2.15  使用BackgroundWorker的優缺點 23
1.2.16  多線程與多任務對比 24
1.3  適用並行編程技術的場景 24
1.4  並行編程的優缺點 25
1.5  小結 26
1.6  牛刀小試 26

第2章  任務並行性 29
2.1  技術要求 29
2.2  任務 29
2.3  創建和啟動任務 30
2.3.1  System.Threading.Tasks.Task類 31
2.3.2  System.Threading.Tasks.Task.Factory.StartNew方法 32
2.3.3  System.Threading.Tasks.Task.Run方法 33
2.3.4  System.Threading.Tasks.Task.Delay方法 33
2.3.5  System.Threading.Tasks.Task.Yield方法 34
2.3.6  System.Threading.Tasks.Task.FromResult<T>方法 36
2.3.7  System.Threading.Tasks.Task.FromException和System.Threading.Tasks.Task.FromException<T>方法 37
2.3.8  System.Threading.Tasks.Task.FromCanceled和System.Threading.Tasks.Task.FromCanceled<T>方法 37
2.4  從完成的任務中獲取結果 38
2.5  取消任務 39
2.5.1  創建令牌 40
2.5.2  使用令牌創建任務 40
2.5.3  通過IsCancellationRequested屬性輪詢令牌的狀態 41
2.5.4  註冊請求取消的回調 42
2.6  等待正在運行的任務 44
2.6.1  Task.Wait 44
2.6.2  Task.WaitAll 45
2.6.3  Task.WaitAny 45
2.6.4  Task.WhenAll 46
2.6.5  Task.WhenAny 46
2.7  處理任務異常 47
2.7.1  處理來自單個任務的異常 47
2.7.2  處理來自多個任務的異常 48
2.7.3  使用回調函數處理任務異常 49
2.8  將APM模式轉換為任務 50
2.9  將EAP模式轉換為任務 52
2.10  有關任務的更多信息 54
2.10.1  後續任務 54
2.10.2  使用Task.ContinueWith方法繼續執行任務 54
2.10.3  使用Task.Factory.ContinueWhenAll和Task.Factory.ContinueWhenAll<T>繼續執行任務 55
2.10.4  使用Task.Factory.ContinueWhenAny和Task.Factory.ContinueWhenAny<T>繼續執行任務 56
2.10.5  父任務和子任務 57
2.10.6  創建一個分離的子任務 57
2.10.7  創建一個附加的任務 58
2.11  工作竊取隊列 59
2.12  小結 62
2.13  牛刀小試 62

第3章  實現數據並行 65
3.1  技術要求 65
3.2  從順序循環到並行循環 65
3.2.1  使用Parallel.Invoke方法 66
3.2.2  使用Parallel.For方法 68
3.2.3  使用Parallel.ForEach方法 69
3.3  瞭解並行度 70
3.4  在並行循環中創建自定義分區策略 72
3.4.1  範圍分區 73
3.4.2  塊分區 73
3.5  取消循環 74
3.5.1  使用Parallel.Break 75
3.5.2  使用ParallelLoopState.Stop 76
3.5.3  使用CancellationToken 77
3.6  瞭解並行循環中的線程存儲 79
3.6.1  線程局部變量 79
3.6.2  分區局部變量 80
3.7  小結 81
3.8  牛刀小試 81

第4章  使用PLINQ 83
4.1  技術要求 83
4.2  .NET中的LINQ提供程序 84
4.3  編寫PLINQ查詢 84
4.3.1  關於ParallelEnumerable類 85
4.3.2  編寫第一個PLINQ查詢 85
4.4  在並行執行時保持順序 86
4.4.1  使用AsOrdered()方法 87
4.4.2  使用AsUnOrdered()方法 88
4.5  PLINQ中的合並選項 88
4.5.1  使用NotBuffered合並選項 88
4.5.2  使用AutoBuffered合並選項 89
4.5.3  使用FullyBuffered合並選項 90
4.6  使用PLINQ拋出和處理異常 92
4.7  組合並行和順序LINQ查詢 94
4.8  取消PLINQ查詢 95
4.9  使用PLINQ進行並行編程時要考慮的事項 97
4.10  影響PLINQ性能的因素 97
4.10.1  並行度 97
4.10.2  合並選項 98
4.10.3  分區類型 98
4.10.4  確定是保持順序執行還是轉向並行 98
4.10.5  操作順序 98
4.10.6  使用ForAll 99
4.10.7  強制並行 99
4.10.8  生成序列 99
4.11  小結 100
4.12  牛刀小試 100

第2篇  支持.NET Core中並行性的數據結構
第5章  同步原語 105
5.1  技術要求 105
5.2  關於同步原語 105
5.3  互鎖操作 106
5.3.1  .NET中的內存屏障 108
5.3.2  重新排序 108
5.3.3  內存屏障的類型 109
5.3.4  避免使用構造對代碼進行重新排序 110
5.4  鎖原語 111
5.4.1  鎖的工作方式 111
5.4.2  線程狀態 111
5.4.3  阻塞與自旋 113
5.5  鎖、互斥鎖和信號量 113
5.5.1  鎖 114
5.5.2  互斥鎖 116
5.5.3  信號量 118
5.5.4  ReaderWriterLock 120
5.6  信號原語 120
5.6.1  Thread.Join 120
5.6.2  EventWaitHandle 122
5.6.3  AutoResetEvent 122
5.6.4  ManualResetEvent 123
5.6.5  WaitHandle 125
5.7  輕量級同步原語 129
5.7.1  Slim鎖 129
5.7.2  ReaderWriterLockSlim 130
5.7.3  SemaphoreSlim 131
5.7.4  ManualResetEventSlim 132
5.8  屏障和倒數事件 133
5.9  使用Barrier和CountDownEvent的案例研究 133
5.10  SpinWait 136
5.11  自旋鎖 136
5.12  小結 137
5.13  牛刀小試 138

第6章  使用並發集合 141
6.1  技術要求 141
6.2  並發集合詳解 141
6.2.1  關於IProducerConsumerCollection<T> 142
6.2.2  使用ConcurrentQueue<T> 143
6.2.3  使用隊列解決生產者-消費者問題 143
6.2.4  使用並發隊列解決問題 145
6.2.5  Queue<T>與ConcurrentQueue<T>性能對比 146
6.2.6  使用ConcurrentStack<T> 146
6.2.7  創建並發堆棧 146
6.2.8  使用ConcurrentBag<T> 148
6.2.9  使用BlockingCollection<T> 149
6.2.10  創建BlockingCollection<T> 150
6.3  多生產者-消費者應用場景 151
6.4  使用ConcurrentDictionary<TKey, TValue> 153
6.5  小結 154
6.6  牛刀小試 155

第7章  通過延遲初始化提高性能 157
7.1  技術要求 157
7.2  延遲初始化概念簡析 157
7.3  關於System.Lazy<T> 161
7.3.1  封裝在構造函數中的構造邏輯 161
7.3.2  作為委托傳遞給Lazy<T>的構造邏輯 162
7.4  使用延遲初始化模式處理異常 163
7.4.1  初始化期間沒有異常發生 164
7.4.2  使用異常緩存初始化時出現隨機異常 164
7.4.3  不緩存異常 166
7.5  線程本地存儲的延遲初始化 167
7.6  減少延遲初始化的開銷 169
7.7  小結 171
7.8  牛刀小試 172

第3篇  使用C#進行異步編程
第8章  異步編程詳解 175
8.1  技術要求 175
8.2  程序執行的類型 175
8.2.1  理解同步程序執行 176
8.2.2  理解異步程序執行 177
8.3  適合使用異步編程的情形 178
8.3.1  編寫異步代碼 179
8.3.2  使用Delegate類的BeginInvoke方法 179
8.3.3  使用Task類 181
8.3.4  使用IAsyncResult接口 181
8.4  不宜使用異步編程的情形 183
8.5  使用異步代碼可以解決的問題 183
8.6  小結 184
8.7  牛刀小試 185

第9章  基於任務的異步編程基礎 187
9.1  技術要求 187
9.2  關於async和await關鍵字 187
9.2.1  使用async和await關鍵字的原因 188
9.2.2  異步方法的返回類型 191
9.3  異步委托和Lambda表達式 192
9.4  基於任務的異步模式 192
9.4.1  編譯器方法,使用async關鍵字 193
9.4.2  手動實現TAP 193
9.5  異步代碼的異常處理 194
9.5.1  返回Task並拋出異常的方法 194
9.5.2  從try-catch塊外部調用異步方法並且不帶await關鍵字 194
9.5.3  從try-catch塊內部調用異步方法並且不帶await關鍵字 196
9.5.4  從try-catch塊外部使用await關鍵字調用異步方法 198
9.5.5  返回void的方法 199
9.6  使用PLINQ實現異步 200
9.7  衡量異步代碼的性能 201
9.8  使用異步代碼的準則 203
9.8.1  避免使用異步void 204
9.8.2  使用異步連鎖鏈 204
9.8.3  盡可能使用ConfigureAwait 205
9.9  小結 205
9.10  牛刀小試 205

第4篇  異步代碼的調試、診斷和單元測試
第10章  使用Visual Studio調試任務 209
10.1  技術要求 209
10.2  使用Visual Studio 2019進行調試 209
10.3  如何調試線程 210
10.4  使用並行堆棧窗口 212
10.4.1  使用並行堆棧窗口進行調試 213
10.4.2  線程視圖 213
10.4.3  任務視圖 215
10.4.4  使用並行觀察窗口進行調試 216
10.5  使用並發可視化器 217
10.5.1  利用率視圖 219
10.5.2  線程視圖 219
10.5.3  核心視圖 220
10.6  小結 220
10.7  牛刀小試 221
10.8  深入閱讀 222

第11章  編寫並行和異步代碼的單元測試用例 223
11.1  技術要求 223
11.2  使用.NET Core進行單元測試 224
11.3  瞭解編寫異步代碼的單元測試用例的問題 226
11.4  編寫並行代碼和異步代碼的單元測試用例 228
11.4.1  檢查成功的結果 229
11.4.2  檢查除數為0時的異常結果 229
11.5  使用Moq模擬異步代碼的設置 230
11.6  使用測試工具 232
11.7  小結 233
11.8  牛刀小試 233
11.9  深入閱讀 234

第5篇  .NET Core附加的並行編程功能
第12章  ASP.NET Core中的IIS和Kestrel 237
12.1  技術要求 237
12.2  IIS線程模型 237
12.2.1  避免飢餓算法 238
12.2.2  爬山算法 238
12.3  Kestrel線程模型 239
12.3.1  ASP.NET Core 1.x 241
12.3.2  ASP.NET Core 2.x 241
12.4  微服務中線程的最佳實踐 242
12.4.1  單線程單進程微服務 242
12.4.2  單線程多進程微服務 243
12.4.3  多線程單進程微服務 243
12.4.4  異步服務 243
12.4.5  專用線程池 243
12.5  在ASP.NET MVC Core中使用異步 245
12.5.1  創建異步Web API 245
12.5.2  異步流 248
12.6  小結 251
12.7  牛刀小試 251

第13章  並行編程中的模式 253
13.1  技術要求 253
13.2  MapReduce模式 253
13.2.1  映射和歸約 253
13.2.2  使用LINQ實現MapReduce 254
13.3  聚合 257
13.4  分叉/合並模式 258
13.5  推測處理模式 259
13.6  延遲模式 260
13.7  共享狀態模式 263
13.8  小結 263
13.9  牛刀小試 264

第14章  分佈式存儲管理 265
14.1  技術要求 265
14.2  分佈式系統簡介 265
14.3  共享存儲模型與分佈式存儲模型 267
14.3.1  共享存儲模型 267
14.3.2  分佈式存儲模型 268
14.4  通信網絡的類型 270
14.4.1  靜態通信網絡 270
14.4.2  動態通信網絡 270
14.5  通信網絡的特徵 271
14.5.1  拓撲結構 271
14.5.2  路由算法 272
14.5.3  交換策略 272
14.5.4  流控制 273
14.6  拓撲結構探索 273
14.6.1  線性和環形拓撲 274
14.6.2  網格和環面 275
14.7  使用消息傳遞接口對分佈式存儲電腦進行編程 277
14.7.1  使用MPI的理由 277
14.7.2  在Windows系統上安裝MPI 277
14.7.3  使用MPI的示例程序 277
14.7.4  基本的發送/接收操作 278
14.8  集合通信 279
14.9  小結 280
14.10  牛刀小試 280

附錄  牛刀小試答案 283