Passing Data To A Thread In C# and .NET

How to pass data to a thread in C#. In this article, I will demonstrate how to use the ThreadStart to pass data from your main program to a new thread using the ParameterizedThreadStart.

In my previous article, Managed Thread Pool In C#, I discussed what a managed thread pool is and how we can use it in out app. If you're new to threading, I recommend reading Introduction to Threads in C# and .NET before this article.
There is often a need of passing data from the main thread of a program to a worker threads. The Thread.Start method has an overloaded form that allows code to pass an object from main thread to a new thread. The object can be a simple data type or it can be a complex data type.
The Thread class constructor takes either a ThreadStart delegate or a ParemeterizedThreadStart delegate. The ParemeterizedThreadStart delegate is used when you need to pass data to the thread.
Let’s look at the code snippet in Listing 10 where the Print class has two methods, PrintJob and PrintPerson. The PrintJob method simply prints data passed to it. The PrintPerson expect the data to be a type of Person. The method reads the Person object details and prints them.
We want to execute these methods in two separate worker threads. As you can clearly see, both methods take a parameter of object type. 
  1. public class Print  
  2. {  
  3.     public void PrintJob(object data)  
  4.     {  
  5.         Console.WriteLine("Background PrintJob started.");  
  6.         Thread.Sleep(1000);  
  7.         Console.WriteLine("PrintJob still printing...");  
  8.         Console.WriteLine($"Data: {data}");  
  9.         Thread.Sleep(1000);  
  10.         Console.WriteLine("PrintJob finished.");  
  11.     }  
  13.     public void PrintPerson(object data)  
  14.     {  
  15.         Console.WriteLine("Background PrintPerson started.");  
  16.         Thread.Sleep(1000);  
  17.         Console.WriteLine("PrintPerson still printing...");  
  18.         Person p = (Person)data;  
  19.         Console.WriteLine($"Person {p.Name} is a {p.Sex} of {p.Age} age.");  
  20.         Thread.Sleep(1000);  
  21.         Console.WriteLine("PrintPerson finished.");  
  22.     }  
  23. }  
Listing 10.
Now, we will see how to pass an object type from the main thread to a worker thread.
The code snippet in Listing 11 starts a new worker thread that executes the PrintJob method. Since the PrintJob is a ParemeterizedThreadStart delegate, the Start method takes a parameter. In this case, I pass a string as a parameter. 
  1. // Create a thread with a ParemeterizedThreadStart  
  2. Print p = new Print();  
  3. Thread workerThread = new Thread(p.PrintJob);  
  4. // Start thread with a parameter  
  5. workerThread.Start("Some data");  
Listing 11.
The PrintPerson method of the Print class takes a complex object of type Person. In code snippet in Listing 12, I create a Person class and pass it as a parameter of the Thread.Start method.
  1. // Pass a class object to a worker thread  
  2. Person mahesh = new Person("Mahesh Chand", 40, "Male");  
  3. Thread workerThread2 = new Thread(p.PrintPerson);  
  4. workerThread2.Start(mahesh);  
Listing 12.
The ParameterizedThreadStart delegate supports only a single parameter. To pass complex or multiple data items, you can pass an Array, a collection type, or a tuple type.
Listing 13 is a complete code listing.
  1. using System;  
  2. using System.Threading;  
  3. class Program  
  4. {  
  5.     static void Main()  
  6.     {  
  7.         // Create a thread with a ParemeterizedThreadStart  
  8.         Print p = new Print();  
  9.         Thread workerThread = new Thread(p.PrintJob);  
  10.         // Start thread with a parameter  
  11.         workerThread.Start("Some data");  
  13.         // Pass a class object to a worker thread  
  14.         Person mahesh = new Person("Mahesh Chand", 40, "Male");  
  15.         Thread workerThread2 = new Thread(p.PrintPerson);  
  16.         workerThread2.Start(mahesh);  
  18.         // Main thread  
  19.         for (int i = 0; i < 10; i++)  
  20.         {  
  21.             Console.WriteLine($"Main thread: {i}");  
  22.             Thread.Sleep(200);  
  23.         }  
  25.         Console.ReadKey();  
  26.     }     
  27. }  
  29. public class Print  
  30. {  
  31.     public void PrintJob(object data)  
  32.     {  
  33.         Console.WriteLine("Background PrintJob started.");  
  34.         Thread.Sleep(1000);  
  35.         Console.WriteLine("PrintJob still printing...");  
  36.         Console.WriteLine($"Data: {data}");  
  37.         Thread.Sleep(1000);  
  38.         Console.WriteLine("PrintJob finished.");  
  39.     }  
  41.     public void PrintPerson(object data)  
  42.     {  
  43.         Console.WriteLine("Background PrintPerson started.");  
  44.         Thread.Sleep(1000);  
  45.         Console.WriteLine("PrintPerson still printing...");  
  46.         Person p = (Person)data;  
  47.         Console.WriteLine($"Person {p.Name} is a {p.Sex} of {p.Age} age.");  
  48.         Thread.Sleep(1000);  
  49.         Console.WriteLine("PrintPerson finished.");  
  50.     }  
  51. }  
  53. public class Person  
  54. {  
  55.     public string Name { getset; }  
  56.     public int Age { getset; }  
  57.     public string Sex { getset; }  
  59.     public Person(string name, int age, string sex)  
  60.     {  
  61.         this.Name = name;  
  62.         this.Age = age;  
  63.         this.Sex = sex;  
  64.     }  
  65. }  
Listing 13. 
In this article, I demonstrated how to use the ThreadStart to pass data from your main program to a new thread using the ParameterizedThreadStart. 
A managed thread pool is a recommended method of using system managed threads. Check out my article, Managed Thread Pool In C# for more details.