Table of contents : C# Concurrency Copyright dedication contents front matter preface acknowledgments about this book Who should read this book How this book is organized: A road map About the code liveBook discussion forum about the author about the cover illustration Part 1. Asynchronous programming and multithreading basics 1 Asynchronous programming and multithreading 1.1 What is multithreading? 1.2 Introducing multicore CPUs 1.3 Asynchronous programming 1.4 Using multithreading and asynchronous programming together 1.5 Software efficiency and cloud computing Summary 2 The compiler rewrites your code 2.1 Lambda functions 2.2 Yield return Summary 3 The async and await keywords 3.1 Asynchronous code complexity 3.2 Introducing Task and Task 3.2.1 Are we there yet? 3.2.2 Wake me up when we get there 3.2.3 The synchronous option 3.2.4 After the task has completed 3.3 How does async/await work? 3.4 async void methods 3.5 ValueTask and ValueTask 3.6 What about multithreading? Summary 4 Multithreading basics 4.1 Different ways to run in another thread 4.1.1 Thread.Start 4.1.2 The thread pool 4.1.3 Task.Run 4.2 Accessing the same variables from multiple threads 4.2.1 No shared data 4.2.2 Immutable shared data 4.2.3 Locks and mutexes 4.2.4 Deadlocks 4.3 Special considerations for native UI apps 4.4 Waiting for another thread 4.5 Other synchronization methods 4.6 Thread settings 4.6.1 Thread background status 4.6.2 Language and locale 4.6.3 COM Apartment 4.6.4 Current user 4.6.5 Thread priority Summary 5 async/await and multithreading 5.1 Asynchronous programming and multithreading 5.2 Where does code run after await? 5.3 Locks and async/await 5.4 UI threads Summary 6 When to use async/await 6.1 Asynchronous benefits on servers 6.2 Asynchronous benefits on native client applications 6.3 The downside of async/await 6.3.1 Asynchronous programming is contagious 6.3.2 Asynchronous programming has more edge cases 6.3.3 Multithreading has even more edge cases 6.3.4 async/await is expensive 6.4 When to use async/await Summary 7 Classic multithreading pitfalls and how to avoid them 7.1 Partial updates 7.2 Memory access reordering 7.3 Deadlocks 7.4 Race conditions 7.5 Synchronization 7.6 Starvation Summary Part 2. Advanced uses of async/await and multithreading 8 Processing a sequence of items in the background 8.1 Processing items in parallel 8.1.1 Processing items in parallel with the Thread class 8.1.2 Processing items in parallel with the thread pool 8.1.3 Asynchronously processing items in parallel 8.1.4 The Parallel class 8.2 Processing items sequentially in the background 8.2.1 Processing items sequentially in the background with the Thread class 8.2.2 The work queue pattern and BlockingCollection 8.2.3 Processing important items with persistent queues Summary 9 Canceling background tasks 9.1 Introducing CancellationToken 9.2 Canceling using an exception 9.3 Getting a callback when the caller cancels our operation 9.4 Implementing timeouts 9.5 Combining cancellation methods 9.6 Special cancellation tokens Summary 10 Await your own events 10.1 Introducing TaskCompletionSource 10.2 Choosing where continuations run 10.3 Example: Waiting for initialization 10.4 Example: Adapting old APIs 10.5 Old-style asynchronous operations (BeginXXX, EndXXX) 10.6 Example: Asynchronous data structures Summary 11 Controlling on which thread your asynchronous code runs 11.1 await-threading behavior 11.1.1 await in UI threads 11.1.2 await in non-UI threads 11.2 Synchronization contexts 11.3 Breaking away—ConfigureAwait(false) 11.4 More ConfigureAwait options 11.5 Letting other code run: Task.Yield 11.6 Task schedulers Summary 12 Exceptions and async/await 12.1 Exceptions and asynchronous code 12.2 await and AggregateException 12.3 The case of the lost exception 12.4 Exceptions and async void methods Summary 13 Thread-safe collections 13.1 The problems with using regular collections 13.2 The concurrent collections 13.2.1 ConcurrentDictionary 13.2.2 BlockingCollection 13.2.3 Async alternatives for BlockingCollection 13.2.4 ConcurrentQueue and ConcurrentStack 13.2.5 ConcurrentBag 13.2.6 When to use the concurrent collections 13.2.7 When not to use the concurrent collections 13.3 The immutable collections 13.3.1 How immutable collections work 13.3.2 How to use the immutable collections 13.3.3 ImmutableInterlocked 13.3.4 ImmutableDictionary 13.3.5 ImmutableHashSet and ImmutableSortedSet 13.3.6 ImmutableList 13.3.7 ImmutableQueue and ImmutableStack 13.3.8 ImmutableArray 13.3.9 When to use the immutable collections 13.4 The frozen collections 13.4.1 When to use the frozen collections Summary 14 Generating collections asynchronously/await foreach and IAsyncEnumerable 14.1 Iterating over an asynchronous collection 14.2 Generating an asynchronous collection 14.3 Canceling an asynchronous collection 14.4 Other options 14.5 IAsyncEnumerable and LINQ 14.6 Example: Iterating over asynchronously retrieved data 14.7 Example: BlockingCollection-like asynchronous queue Summary index