chapter four

4 Multithreading basics

 

This chapter covers

  • Understanding threads
  • Starting threads
  • Waiting for threads
  • Accessing shared data and using locks
  • Understanding Deadlocks

In the previous chapter we talked about how asynchronous programming works in C# with the async and await keywords, I talked about making code run later with ContinueWith or the await keyword, but I completely ignored who is going to run the code later.

Like we talked about back in chapter one, the operating system construct that runs code is called a thread. the system can run many pieces of code at the same time (much more than the number of CPU cores) by switching between them quickly. There is a hardware timer inside the CPU and every time that timer ticks the operating system stops whatever code that is running and switches to another thread. If the system does this fast enough it will look like all the threads are constantly running at the same time.

In this chapter we are going to talk about how you can use threads to run code in parallel, in the next chapter we are going to talk about how this applies to async-await.

When a process starts you get one thread that runs our Main method (and a few other threads controlled by the system, but we’re going to ignore them for now). This is thread is called the main thread. Now we are going to see how you can run on other threads so you can make multiple pieces of code run at the same time.

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.3 Special considerations for native UI apps

4.4 Summary