- What Are Threads In C#?
- When To Use Thread In C#?
- Limitations Of Threads In C#
- C# Start New Thread
- Difference Between Foreground And Background Thread In C#
- C# Start Thread With Parameters
- Thread Life Cycle In C#
- C# Stop Thread
- Further Reading
What Are Threads in C#?
In CLR or Windows environment each program you run creates a virtual address space and known as process. Contents of a process is not addressable directly to another process.
Each process has its own thread(s) and this thread has access to all data in that process, But if we are .Net programmers and so we are, we have managed code and we can say that this thread as managed thread which has access to all data in that process’s app domain which is subdivision of process
Know more what is the difference in managed and unmanaged code, memory and size here.
So a process in its execution lifetime has this main thread that runs execution starting from the main method and in during this execution it may create one or more thread. This thread can execute code of the same executable or code defined in other dll in the same process
In Windows world, if a process does not have a thread it gets terminate.
When To Use Thread In C#?
You can use threads in the following cases:
Scalability (Be parallel) - If you have long running CPU bound operations, like to compute if 80 digit number is prime or not, you can scale this operation by paralleling this operation to multiple threads
Responsive - You can keep client application responsive by keeping off lengthy operations from main thread (like CPU bound operation) and thus can also leverage the benefit of canceling the task
Leverage asynchronous technique - If you have IO bound operation such reading a web content it may require some time in order of minutes, so you can leverage another thread to wait for this operation while you perform other task and thus even keep UI responsive
C# provides async await syntax for this kind of asynchronous technique.
Being asynchronous is not parallel it just keeps the application responsive. Asynchronous means not waiting for an operation to finish, but registering a listener instead.
In general, use parallel threads (using Thread class and Task class in C#) or asynchronous technique (using C# async await keyword) depending upon whether the problem is CPU bound or IO bound respectively.
Thumb rule is to use threads for CPU bound operation and async for IO bound operation for a client application, and always use async for a server application.
You can find some serious examples of CPU bound and non-CPU bound problems here.
Limitations Of Threads In C#
Multithreading leads to complex code thus reduce readability. It also increases the difficulty of debugging and testing. However, you can overcome this with good programming practice and commented code.
Also in single core processor machine, Threads increase execution time (a little) than a sequential program, due to context switching. But still for scalability its good to use threads because when it will run on multi-core processor machine it will scale better.
Bottom line, Ignore all these limitations.
C# Start New Thread
Threads in C# are modelled by Thread Class. When a process starts (you run a program) you get a single thread (also known as the main thread) to run your application code. To explicitly start another thread (other than your application main thread) you have to create an instance of thread class and call its Start method to run the thread using C#, Let’s see an example
When you run this program you may see Press Enter to terminate! message first and then Hello World! as they both run in parallel, so it is not guaranteed which execute first.
We can use Thread’s
Join() method to halt our main thread until reference thread (that is “t” variable in our case) is truly shutdown.
Another method to do this would be by using boolean
IsAlive property of thread which gives instantaneous snapshot of thread’s state whether it is running or not. Like this,
t.Join() is the recommended method.
Here is an example
Thread doesn’t start running until you call
thread.Start() method, So before calling this Start method you can set some properties of a thread like its name and priority. Setting name of the thread will only help you in debugging, by setting name you can easily point out your thread in Visual Studio Thread window, Let’s see an example
Difference Between Foreground And Background Thread In C#
There is also this another thread property IsBackground. If set to true your thread will be a background thread otherwise it will be a foreground thread, by default its false so it will always be a foreground thread, Let’s see an example
Suppose if a foreground thread is the only thread (your main thread is done with execution and terminated) in your process, so your process is about to exit. However, it won’t, your process will wait for foreground thread to complete its execution. Thus, It will prevent application to exit until the foreground thread is done with the execution.
Background thread will exit as soon as your process exits even though background thread is not completely done with the execution.
Learn more about how foreground & background threads work in C# .NET here.
C# Start Thread With Parameters
As you saw in example before that we pass method name to thread constructor parameter like this,
We able to do this because this thread contructor takes delegate as parameter. Its supports two type of delegates, Here is the definition of first delegate
this we already saw in the above example, other is
If your custom method takes argument you can pass a ParameterizedThreadStart delegate to constructor, Let’s see an example
Did you notice now we need to pass the Speak method argument to Start method.
So far we have used only static method. However, you can also use instance methods as a thread constructor parameter, Let’s see an example
In the above example, we used ParameterizedThreadStart delegate however same applies to ThreadStart delegate, both of them can be used with an instance method.
Thread Life Cycle In C#
So now we know how thread class models a thread. This thread, however, doesn’t stay for infinity and has lifespan which is up to the return of the thread delegate method, Let’s see an example
Here, line no 33 will be the last execution statement after which thread will be shutdown.
Some other reasons of thread shutdown are as follows:
Thread also gets exit if it runs into an unhandled exception. This exception is considered as synchronous exception which occurs in normal sequential program like IndexOutOfRangeExecption.
This exception is an explicit exception raised by calling thread’s Abort or Interrupt method in the running thread by some other thread which has reference to the running thread. This exception also exits thread execution. However, this is not a recommended method to shutdown a thread as it leaves the program to some improper state.
C# Stop Thread
Lets start with an example this time,
Here we used a boolean field to signal another thread Speak method to stop running when
_cancel is set to true.
Did you notice how we need to set the
_cancel field as volatile. JIT usually cache this kind of fields as it doesn’t seem to change within Speak method in the loop. By setting it to volatile we are signaling JIT not to cache this field because it is liable to change.
You can use your own communication mechanism to tell the ThreadStart method to finish, which is recommended method. Alternatively the Thread class has in-built support for instructing the thread to stop. The two principle methods are
Thread.Abort(), which is not recommended.
In the next post we will learn about C# Threadpool. A thread pool is a collection of threads that can be used to perform several tasks in the background. This leaves the primary thread free to perform other tasks asynchronously.
C# Threadpool - This article explains how to use C# Threadpool. A thread pool is a collection of threads that can be used to perform several tasks in the background. This leaves the primary thread free to perform other tasks asynchronously.
C# Task - C# Task is one of the central elements of the task-based asynchronous pattern first introduced in the .NET Framework 4. This article serves to be a quick guide for using Tasks in C#. It discusses different methods to create tasks and handle their execution.
Async And Await In C# - In this article, you’ll learn what are async and await keywords in C#, and how to use async-await feature along with Task for asynchronous programming. You will also learn about the application of this asynchronous principle across .Net Applications.
Subscribe to Code with Shadman
Get the latest posts delivered right to your inbox