Threading in C# Joseph Albahari

Last updated 2011-4-27

Interested in a book on C# and .NET by the same author? See www.albahari.com/nutshell/

Table of Contents

Part 1: Getting Started ...... 4 Introduction and Concepts ...... 4 Join and Sleep ...... 6 How Threading Works ...... 7 Threads vs Processes ...... 7 Threading’s Uses and Misuses ...... 8 Creating and Starting Threads ...... 8 Passing Data to a Thread ...... 9 Naming Threads ...... 11 Foreground and Background Threads ...... 11 Thread Priority...... 12 Exception Handling ...... 12 Thread Pooling ...... 14 Entering the via TPL ...... 15 Entering the Thread Pool Without TPL ...... 16 Optimizing the Thread Pool ...... 17

Part 2: Basic Synchronization ...... 19 Synchronization Essentials ...... 19 Blocking ...... 19 Blocking Versus Spinning ...... 20 ThreadState ...... 20 Locking ...... 21 Monitor.Enter and Monitor.Exit ...... 22 Choosing the Synchronization Object ...... 23 When to ...... 23 Locking and Atomicity ...... 24 Nested Locking ...... 24 Deadlocks ...... 25 Performance ...... 26 Mutex ...... 26 Semaphore ...... 27

© 2006-2010 Joseph Albahari, O’Reilly Media, Inc. All rights reserved. www.albahari.com/threading/ 1

Thread Safety ...... 28 Thread Safety and .NET Framework Types ...... 28 Thread Safety in Application Servers ...... 30 Rich Client Applications and Thread Affinity ...... 30 Immutable Objects ...... 32 Signaling with Event Wait Handles ...... 33 AutoResetEvent ...... 33 ManualResetEvent ...... 37 CountdownEvent ...... 38 Creating a Cross-Process EventWaitHandle ...... 39 Wait Handles and the Thread Pool ...... 39 WaitAny, WaitAll, and SignalAndWait ...... 40 Synchronization Contexts ...... 41 Reentrancy ...... 43

Part 3: Using Threads ...... 44 The Event-Based Asynchronous Pattern ...... 44 BackgroundWorker ...... 45 Using BackgroundWorker ...... 45 Subclassing BackgroundWorker ...... 47 Interrupt and Abort ...... 48 Interrupt ...... 49 Abort ...... 49 Safe Cancellation ...... 50 Cancellation Tokens ...... 51 Lazy Initialization ...... 52 Lazy ...... 53 LazyInitializer...... 53 Thread-Local Storage ...... 54 [ThreadStatic] ...... 54 ThreadLocal ...... 55 GetData and SetData ...... 55 Timers ...... 56 Multithreaded Timers ...... 56 Single-Threaded Timers ...... 58

Part 4: Advanced Topics ...... 59 Nonblocking Synchronization ...... 59 Memory Barriers and Volatility ...... 59 Interlocked ...... 63 Signaling with Wait and Pulse ...... 65 How to Use Wait and Pulse ...... 65 Producer/Consumer Queue ...... 67 Wait Timeouts ...... 70 Two-Way Signaling and Races ...... 71 Simulating Wait Handles ...... 72 Writing a CountdownEvent ...... 74 Thread Rendezvous ...... 75

© 2006-2010 Joseph Albahari, O’Reilly Media, Inc. All rights reserved. www.albahari.com/threading/ 2

The Barrier Class ...... 75 Reader/Writer Locks ...... 77 Upgradeable Locks and Recursion ...... 78 Suspend and Resume ...... 80 Aborting Threads ...... 80 Complications with Thread.Abort ...... 82 Ending Application Domains ...... 83 Ending Processes ...... 84

Part 5: Parallel Programming ...... 85 Parallel Programming ...... 85 Why PFX? ...... 85 PFX Concepts ...... 86 PFX Components...... 86 When to Use PFX ...... 87 PLINQ ...... 87 Parallel Execution Ballistics ...... 89 PLINQ and Ordering ...... 89 PLINQ Limitations ...... 90 Example: Parallel Spellchecker ...... 90 Functional Purity ...... 92 Calling Blocking or I/O-Intensive Functions ...... 92 Cancellation ...... 94 Optimizing PLINQ ...... 94 Parallelizing Custom Aggregations ...... 96 The Parallel Class ...... 100 Parallel.Invoke ...... 100 Parallel.For and Parallel.ForEach ...... 100 Task Parallelism ...... 105 Creating and Starting Tasks ...... 105 Waiting on Tasks ...... 107 Exception-Handling Tasks ...... 108 Canceling Tasks ...... 109 Continuations ...... 110 Task Schedulers and UIs ...... 113 TaskFactory ...... 114