Introduction
Here I will discuss the concepts of threading / multi-threading in C# using program. I would recommend that you should copy the given programs in your Visual Studio and run the program after making changes as you wish to see its impact. For example, if you have doubts about whether a method invoked by thread can return some value or not, just modify the return type of the method accordingly. Compile, run the program. You will get your answers while compiling or running the program. It will help you not only to understand the concepts but remember as well.
using System;
namespace TestConsole
{
class Program
{
public static void Main(string[] args)
{
var traditionalThread = new TraditionalThread();
traditionalThread.TestTraditionalThreadWithoutParameters();
traditionalThread.TestTraditionalThreadWithParameters();
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Threading;
namespace TestConsole
{
public class TraditionalThread
{
public void TestTraditionalThreadWithoutParameters()
{
Console.WriteLine("Testing threads with methods not having parameter");
var threads = new List<Thread>
{
new Thread(PrintNumbers),
new Thread(new ThreadStart
(PrintNumbers)), new Thread(PrintNumbers),
new Thread(() => Console.WriteLine
("You can use lambda expression or anonymous methods as well"))
};
threads.ForEach(t => t.Start()); threads.ForEach(t => t.Join()); }
public void TestTraditionalThreadWithParameters()
{
Console.WriteLine("Testing threads with methods having parameter");
var threads = new List<Thread>
{
new Thread(new ParameterizedThreadStart
(PrintParticularCharacter)), new Thread((toPrint) =>
{
for (var count = 0; count < 10; count++)
Console.WriteLine("ThreadId : {0} and Value : {1}",
Thread.CurrentThread.ManagedThreadId, toPrint);
})
};
threads[0].Start("X");
threads[1].Start("Y");
threads.ForEach(t => t.Join()); }
private static void PrintNumbers() {
for (var count = 0; count < 10; count++)
{
Console.WriteLine("ThreadId : {0}
and Value : {1}", Thread.CurrentThread.ManagedThreadId, count);
Thread.Sleep(1000); }
}
private static void PrintParticularCharacter(object toPrint) {
for (var count = 0; count < 10; count++)
{
Console.WriteLine("ThreadId : {0}
and Value : {1}", Thread.CurrentThread.ManagedThreadId, toPrint);
Thread.Sleep(1000); }
}
}
}
Below are some terms/concepts you must know.
Thread.Sleep
You can call this method on any thread object. It makes that thread sleep for a given time period. It accepts time period in milliseconds. It does not consume CPU cycles while sleeping.
Example
t1.sleep(1000);
Thread.Join
You can call this method on any thread object. It makes the parent thread wait for the child thread. The main/parent thread will wait for the child thread to complete.
Example
t1.Join();
t2.Join(2000);
Background and Foreground Threads
By default, threads you create explicitly are foreground threads. Foreground threads keep the application alive for as long as any one of them is running, whereas background threads do not. Once all foreground threads finish, the application ends, and any background threads still running abruptly terminate.
You can check if the thread is a background thread or foreground thread by using thread’s property “IsBackground
”.
Thread Pooling >>