Threading is a pretty core concept, but I felt it might be necessary to give it a brief explanation before moving on to some WPF-specific concerns for threads. If you are already familiar with threads, these aren’t the droids you’re looking for.
If you think about the flow of a simple application that does not use multithreading, you’ll find that you can basically draw a line on a sheet of paper and label the events of the process as a straight line of consecutive actions:
This method is often very stifling to the developer, as it limits what you can do. At times, you want another action to be able to perform simultaneously. A classic case is to allow a user to cancel an action. In this case, the user is allowed to interact with the process while it is busy. That is, the line of execution cannot be drawn so straight:
You can perform this (seemingly) concurrent operation by using threads. Threads are similar to processes in that they are a set of instructions for the computer to perform; however, processes and threads differ in that separate threads share resources under the same process, while processes are independent of each other. You can think of separate threads as workers who share materials and tools, but have separate instructions to perform at the same time.
Every application has at least one thread: the main thread of execution. This is represented by the green line above; it is the thread that starts the application and is the top of the family tree of the cute little baby threads that are spawned during your application’s execution. When you have an action that you wish to perform concurrently with the main thread, you create a new thread, give it a set of tasks, and start its execution. In C#, simply instantiate a Thread object using a delegate and start it.
Thread worker = new Thread(delegate() { // actions to perform on separate thread }); worker.Start(); |
A delegate is a reference type to a function that serves to give the thread an action to perform. So, if you think of a thread as a worker separate from the main thread, you can think of a delegate as that worker’s to-do list.
In C#, there is also a Delegate class. This class is used as a base for derived delegates – you can use this if you want to have a custom delegate, which is useful for defining to-do lists that have specific requirements. For example, events use custom delegates in order to ensure that the event handler has the proper information when it reacts to the event. So, if you want to create a MouseDown event handler, you must define a handler that accepts the sender of the event, as well as information regarding the mouse’s state.
Seems simple enough, right? Well, things can actually get quite complicated. I’ll address some complexities of multithreading in another post.
Pingback: Threading Complexities | Andrew Eichacker
Pingback: Multithreading in WPF | Andrew Eichacker