Cover....1
Title Page....2
Copyright and Credits....3
Contributors....5
Table of Contents....8
Preface....14
Part 1: Introduction to Threading in .NET....20
Chapter 1: Managed Threading Concepts....22
Technical requirements....23
.NET threading basics....23
Threads and processes....23
When should we use multithreading in .NET?....24
Background threads....24
What is managed threading?....27
Creating and destroying threads....28
Creating managed threads....28
Pausing thread execution....30
Destroying managed threads....32
Handling threading exceptions....32
Synchronizing data across threads....33
Synchronizing code regions....33
Manual synchronization....35
Scheduling and canceling work....37
Scheduling managed threads....37
Canceling managed threads....40
Summary....44
Questions....44
Chapter 2: Evolution of Multithreaded Programming in .NET....46
Technical requirements....47
.NET threading through the years....47
C# 4 and .NET Framework 4.0....47
C# 5 and 6 and .NET Framework 4.5.x....48
C# 7.x and .NET Core 2.0....48
C# 8 and .NET Core 3.0....49
C# 10 and .NET 6....50
Beyond threading basics....50
Managed thread pool....51
Threading and timers....52
Introduction to parallelism....56
Using Parallel.Invoke....57
Using Parallel.ForEach....59
Basics of Parallel LINQ....60
Introduction to concurrency....62
ConcurrentBag....63
ConcurrentQueue....64
ConcurrentStack....64
BlockingCollection....65
ConcurrentDictionary....66
Basics of async and await....66
Understanding the async keyword....66
Writing an async method....67
Choosing the right path forward....69
Summary....70
Questions....70
Chapter 3: Best Practices for Managed Threading....72
Technical requirements....72
Handling static objects....73
Static data and constructors....73
Controlling shared access to static objects....75
Managing deadlocks and race conditions....79
Mitigating deadlocks....80
Avoiding race conditions....82
Threading limits and other recommendations....85
Summary....88
Questions....88
Chapter 4: User Interface Responsiveness and Threading....90
Technical requirements....90
Leveraging background threads....91
Which threads are background threads?....91
Using async, await, tasks, and WhenAll....92
Using the thread pool....101
Updating the UI thread without exceptions....104
Summary....107
Questions....107
Part 2: Parallel Programming and Concurrency with C#....108
Chapter 5: Asynchronous Programming with C#....110
Technical requirements....111
More about asynchronous programming in .NET....111
I/O-bound operations....111
CPU-bound operations....113
Nested async methods....116
Working with Task objects....121
Exploring Task methods....122
Exploring Task properties....124
Interop with synchronous code....125
Executing async from synchronous methods....126
Executing synchronous code as async....129
Working with multiple background tasks....132
Asynchronous programming best practices....133
Summary....134
Questions....135
Chapter 6: Parallel Programming Concepts....136
Technical requirements....136
Getting started with the TPL....137
I/O-bound operations....137
CPU-bound operations....138
Parallel loops in .NET....138
Basic Parallel.For loops....138
Parallel loops with thread-local variables....143
Simple Parallel.ForEach loops....145
Cancel a Parallel.ForEachAsync loop....147
Relationships between parallel tasks....150
Under the covers of Parallel.Invoke....150
Understanding parallel child tasks....151
Common pitfalls with parallelism....156
Parallelism is not guaranteed....156
Parallel loops are not always faster....156
Beware of blocking the UI thread....156
Thread safety....157
UI controls....157
ThreadLocal data....157
Summary....157
Questions....158
Chapter 7: Task Parallel Library (TPL) and Dataflow....160
Technical requirements....161
Introducing the TPL Dataflow library....161
Why use the TPL Dataflow library?....164
Types of dataflow blocks....165
Implementing the producer/consumer pattern....170
Creating a data pipeline with multiple blocks....178
Manipulating data from multiple data sources....182
Summary....184
Questions....184
Chapter 8: Parallel Data Structures and Parallel LINQ....186
Technical requirements....187
Introducing PLINQ....187
PLINQ and performance....188
Creating a PLINQ query....189
Query syntax versus method syntax....190
Converting LINQ queries to PLINQ....191
Handling exceptions with PLINQ queries....193
Preserving data order and merging data with PLINQ....197
PLINQ data order samples....197
Using WithMergeOptions in PLINQ queries....201
Data structures for parallel programming in .NET....205
Concurrent collections....206
Synchronization primitives....206
Summary....207
Questions....208
Chapter 9: Working with Concurrent Collections in .NET....210
Technical requirements....211
Using BlockingCollection....211
BlockingCollection details....211
Using BlockingCollection with Parallel.ForEach and PLINQ....212
Using ConcurrentBag....218
Using ConcurrentDictionary....223
Using ConcurrentQueue....229
Using ConcurrentStack....232
Summary....233
Questions....234
Part 3: Advanced Concurrency Concepts....236
Chapter 10: Debugging Multithreaded Applications with Visual Studio....238
Technical requirements....239
Introducing multithreaded debugging....239
Debugging threads and processes....240
Debugging a project with multiple threads....240
Exploring the Threads window....243
Switching and flagging threads....245
Switching threads....245
Flagging threads....245
Freezing threads....247
Debugging a parallel application....248
Using the Parallel Stacks window....248
Using the Parallel Watch window....253
Summary....257
Questions....257
Chapter 11: Canceling Asynchronous Work....258
Technical requirements....258
Canceling managed threads....259
Canceling parallel work....261
Canceling a parallel loop....262
Canceling a PLINQ query....264
Discovering patterns for thread cancellation....266
Canceling with polling....266
Canceling with callbacks....269
Canceling with wait handles....273
Handling multiple cancellation sources....276
Summary....278
Questions....278
Chapter 12: Unit Testing Async, Concurrent, and Parallel Code....280
Technical requirements....281
Unit testing asynchronous code....281
Unit testing concurrent code....287
Unit testing parallel code....291
Checking for memory leaks with unit tests....295
Summary....299
Questions....300
Assessments....302
Index....308
Other Books You May Enjoy....317
.NET has included managed threading capabilities since the beginning, but early techniques had inherent risks: memory leaks, thread synchronization issues, and deadlocks. This book will help you avoid those pitfalls and leverage the modern constructs available in .NET 6 and C# 10, while providing recommendations on patterns and best practices for parallelism and concurrency. Parallel, concurrent, and asynchronous programming are part of every .NET application today, and it becomes imperative for modern developers to understand how to effectively use these techniques.
This book will teach intermediate-level .NET developers how to make their applications faster and more responsive with parallel programming and concurrency in .NET and C# with practical examples. The book starts with the essentials of multi-threaded .NET development and explores how the language and framework constructs have evolved along with .NET. You will later get to grips with the different options available today in .NET 6, followed by insights into best practices, debugging, and unit testing.
By the end of this book, you will have a deep understanding of why, when, and how to employ parallelism and concurrency in any .NET application.
This book is for beginner to intermediate-level .NET developers who want to employ the latest parallel and concurrency features in .NET when building their applications. Readers should have a solid understanding of the C# language and any version of the .NET Framework or .NET Core.