How do you start a thread with parameters in C#?
-
The answer to this question varies widely across versions of the runtime - is a 3.5 answer fine? – quillbreaker Jul 28 '09 at 18:39
-
6Wow. I've been editing some of your old questions, but it could be a full-time job. I had forgotten, uh, how much you've improved over the years. :-) – John Saunders Dec 26 '13 at 19:56
-
3If I asked such a brief question I would get 5 negative scores or even more! Although the question and answer helped me. – Muhammad Musavi Dec 24 '19 at 06:28
-
This answer still helpful after 12 years, @MuhammadMusavi this question was asked 9 years ago (2019) so no wonder you would get negative if this were to be asked now considering there are a lot of articles for this question and materials – Aimkiller Apr 22 '22 at 06:19
15 Answers
One of the 2 overloads of the Thread constructor takse a ParameterizedThreadStart delegate which allows you to pass a single parameter to the start method. Unfortunately though it only allows for a single parameter and it does so in an unsafe way because it passes it as object. I find it's much easier to use a lambda expression to capture the relevant parameters and pass them in a strongly typed fashion.
Try the following
public Thread StartTheThread(SomeType param1, SomeOtherType param2) {
var t = new Thread(() => RealStart(param1, param2));
t.Start();
return t;
}
private static void RealStart(SomeType param1, SomeOtherType param2) {
...
}

- 733,204
- 149
- 1,241
- 1,454
-
47+1: Even though the currently selected answer is absolutely correct, this one by JaredPar is the better one. It simply is the best solution for most practical cases. – galaktor Oct 10 '09 at 10:27
-
3This solution is much better then the standrard ParameterizedThreadStart – Piotr Owsiak Jul 30 '10 at 13:33
-
5Nice so simple. Just wrap any call in "new Thread(() => FooBar() ).Start(); – Thomas Jespersen Nov 29 '10 at 15:02
-
13Awesome, this is for VB.NET guys `Dim thr As New Thread(Sub() DoStuff(settings))` – dr. evil Sep 17 '11 at 22:55
-
@ThomasJespersen in your example `new Thread(FooBar).Start();` works just as well, sparing a closure. – Clément Mar 24 '13 at 09:53
-
@JaredPar, `public Task(Delegate method) { Method = method; Thread = new Thread(() => method); }` does not work. How can I make it work so I can have a generic (not Generic) solution? – toddmo Dec 06 '13 at 18:02
-
@JaredPar in what sense is `ParameterizedThreadStart` unsafe? Do you mean static type checking, or is it something else? – bavaza Jan 09 '14 at 09:49
-
3
-
Can someone translate this to VB? I'm stuck with it, and can't figure out how to write the lamba. – David Krider Aug 08 '14 at 14:37
-
1Beware: If the parameter values change before the thread is actually started, the values passed will also be changed. See the comments on the accepted answer here: http://stackoverflow.com/questions/3360555/how-to-pass-parameters-to-threadstart-method-in-thread – Kaganar Apr 08 '15 at 18:21
Yep :
Thread t = new Thread (new ParameterizedThreadStart(myMethod));
t.Start (myParameterObject);

- 47,018
- 22
- 121
- 208

- 5,969
- 10
- 42
- 61
-
14is this the same: ThreadStart processTaskThread = delegate { ProcessTasks(databox.DataboxID ); }; new Thread(processTaskThread).Start(); – JL. Jul 28 '09 at 18:35
-
1The `databox.DataboxID` will be encapsulated in the delegate you create (this is called a "closure"), so this is also a way to do it. – Thomas Jul 28 '09 at 18:37
-
Use ParameterizedThreadStart to be able to pass parameters to that delegate when you call Start method. You are using a ThreadStart delegate which does not expect a method with a parameter in its signature, that is wrong in your case. – huseyint Jul 28 '09 at 18:48
-
44
-
4In this case `void MyParamObject(object myUrl){ //do stuff }` should have parameter type `object` – Elshan Oct 24 '14 at 03:21
-
25-1 because the answer assumes that the OP knows how to use `ParameterizedThreadStart` and clearly from the question text, that is probably not the case. – JYelton Feb 06 '15 at 18:02
-
1Or even simpler `vart = new Thread (myMethod);` `t.Start (myParameterObject);` – Siyavash Hamdi Apr 22 '17 at 17:01
-
3I have this error Error CS0123 No overload for 'UpdateDB' matches delegate 'ParameterizedThreadStart' – Omid Farvid Oct 07 '17 at 16:05
-
Shouldn't be the parameter like `ParameterizedThreadStartObject(myMethod)`? – Sebastian Xawery Wiśniowiecki Apr 23 '20 at 18:27
-
1
You can use lambda expressions
private void MyMethod(string param1,int param2)
{
//do stuff
}
Thread myNewThread = new Thread(() => MyMethod("param1",5));
myNewThread.Start();
this is so far the best answer i could find, it's fast and easy.

- 3,676
- 1
- 20
- 23
-
6
-
1
-
2This is a lambda expression, some info can be found on these addresses: msdn.microsoft.com/en-us/library/vstudio/bb397687.aspx | http://www.codeproject.com/Articles/24255/Exploring-Lambda-Expression-in-C | http://www.dotnetperls.com/lambda – Georgi-it Aug 13 '13 at 12:31
-
1This worked for me. I tried the ParameterizedThreadStart and variations of it but had no joy. I was using .NET Framework 4 in a supposedly simple console application. – Daniel Hollinrake Mar 17 '14 at 12:18
-
1This works best for people who are used to these kind of delegates. Might be difficult for beginners to udnerstand. This is clean for C# standards though. The accepted answer doesn't work for me and I don't have the time to find out why. – Bitterblue Jun 19 '18 at 08:32
-
-
How is this answer different from [JaredPar's answer](https://stackoverflow.com/a/1195915/7740405) ? – Maskim Oct 08 '20 at 06:41
Simple way using lambda like so..
Thread t = new Thread(() => DoSomething("param1", "param2"));
t.Start();
OR you could even delegate
using ThreadStart
like so...
private void DoSomething(int param1, string param2)
{
//DO SOMETHING...
ThreadStart ts = delegate
{
if (param1 > 0) DoSomethingElse(param2, "param3");
};
new Thread(ts).Start();
//DO SOMETHING...
}
OR using .NET 4.5+ even cleaner like so..
private void DoSomething(int param1, string param2)
{
//DO SOMETHING..
void ts()
{
if (param1 > 0) DoSomethingElse(param2, "param3");
}
new Thread(ts).Start();
//DO SOMETHING..
}

- 1,475
- 1
- 21
- 32
Thread thread = new Thread(Work);
thread.Start(Parameter);
private void Work(object param)
{
string Parameter = (string)param;
}
The parameter type must be an object.
EDIT:
While this answer isn't incorrect I do recommend against this approach. Using a lambda expression is much easier to read and doesn't require type casting. See here: https://stackoverflow.com/a/1195915/52551

- 1
- 1

- 34,865
- 12
- 85
- 147
-
1Why are you helping with a code that does not compile ;) `Parameter`? – Sebastian Xawery Wiśniowiecki Apr 23 '20 at 18:31
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(new ParameterizedThreadStart(ThreadMethod));
t.Start("My Parameter");
}
static void ThreadMethod(object parameter)
{
// parameter equals to "My Parameter"
}
}

- 14,953
- 15
- 56
- 78
-
4This is giving me "No overload for 'DoWork' matches delegate 'System.Threading.ParameterizedThreadStart' – fIwJlxSzApHEZIl Jan 09 '13 at 21:41
-
1What would be the difference if you just passed ThreadMethod in the Thread t initialization? – Joe Feb 20 '14 at 22:19
-
As has already been mention in various answers here, the Thread
class currently (4.7.2) provides several constructors and a Start
method with overloads.
These relevant constructors for this question are:
public Thread(ThreadStart start);
and
public Thread(ParameterizedThreadStart start);
which either take a ThreadStart
delegate or a ParameterizedThreadStart
delegate.
The corresponding delegates look like this:
public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(object obj);
So as can be seen, the correct constructor to use seems to be the one taking a ParameterizedThreadStart
delegate so that some method conform to the specified signature of the delegate can be started by the thread.
A simple example for instanciating the Thread
class would be
Thread thread = new Thread(new ParameterizedThreadStart(Work));
or just
Thread thread = new Thread(Work);
The signature of the corresponding method (called Work
in this example) looks like this:
private void Work(object data)
{
...
}
What is left is to start the thread. This is done by using either
public void Start();
or
public void Start(object parameter);
While Start()
would start the thread and pass null
as data to the method, Start(...)
can be used to pass anything into the Work
method of the thread.
There is however one big problem with this approach:
Everything passed into the Work
method is cast into an object. That means within the Work
method it has to be cast to the original type again like in the following example:
public static void Main(string[] args)
{
Thread thread = new Thread(Work);
thread.Start("I've got some text");
Console.ReadLine();
}
private static void Work(object data)
{
string message = (string)data; // Wow, this is ugly
Console.WriteLine($"I, the thread write: {message}");
}
Casting is something you typically do not want to do.
What if someone passes something else which is not a string? As this seems not possible at first (because It is my method, I know what I do or The method is private, how should someone ever be able to pass anything to it?) you may possibly end up with exactly that case for various reasons. As some cases may not be a problem, others are. In such cases you will probably end up with an InvalidCastException
which you probably will not notice because it simply terminates the thread.
As a solution you would expect to get a generic ParameterizedThreadStart
delegate like ParameterizedThreadStart<T>
where T
would be the type of data you want to pass into the Work
method. Unfortunately something like this does not exist (yet?).
There is however a suggested solution to this issue. It involves creating a class which contains both, the data to be passed to the thread as well as the method that represents the worker method like this:
public class ThreadWithState
{
private string message;
public ThreadWithState(string message)
{
this.message = message;
}
public void Work()
{
Console.WriteLine($"I, the thread write: {this.message}");
}
}
With this approach you would start the thread like this:
ThreadWithState tws = new ThreadWithState("I've got some text");
Thread thread = new Thread(tws.Work);
thread.Start();
So in this way you simply avoid casting around and have a typesafe way of providing data to a thread ;-)

- 6,324
- 5
- 28
- 44
-
Wow, a downvote without comment... Either my answer is as bad as the cast or the reader did not understood what I tried to point out here ;-) – Markus Safar Dec 11 '18 at 22:19
-
1I found your solution very enlightnen, congratulations. Just wanted to add that I have already tested in Net.Core the following and worked without having to explicity cast! :-) `private static void MyMethod
(T myData) { T message = myData; Console.WriteLine($"the thread wrote: {message}"); }` – Paul Efford Jan 15 '20 at 19:04 -
@PaulEfford Thanks ;-) Your solution seems pretty nice. But you don't get access to type specific information as it will still be boxed to an object, right? (e.g. `message.Length` is not possible and so on) – Markus Safar Jan 16 '20 at 14:13
-
1right... you could message.GetType() and cast if requiered any specific property like `if(myData.GetType() == typeof(string)) { var str = ((string)(object)myData).Length; }`. Anyway, instead of using your threading method I found a bit more comfortable to use `Tasks
`, like for example `tasks.Add(Task.Run(() => Calculate(par1, par2, par3)))`, see my answer below (https://stackoverflow.com/a/59777250/7586301) – Paul Efford Jan 16 '20 at 20:22
I was having issue in the passed parameter. I passed integer from a for loop to the function and displayed it , but it always gave out different results. like (1,2,2,3) (1,2,3,3) (1,1,2,3) etc with ParametrizedThreadStart delegate.
this simple code worked as a charm
Thread thread = new Thread(Work);
thread.Start(Parameter);
private void Work(object param)
{
string Parameter = (string)param;
}

- 61
- 1
- 1
The ParameterizedThreadStart
takes one parameter. You can use that to send one parameter, or a custom class containing several properties.
Another method is to put the method that you want to start as an instance member in a class along with properties for the parameters that you want to set. Create an instance of the class, set the properties and start the thread specifying the instance and the method, and the method can access the properties.

- 687,336
- 108
- 737
- 1,005
You could use a ParametrizedThreadStart delegate:
string parameter = "Hello world!";
Thread t = new Thread(new ParameterizedThreadStart(MyMethod));
t.Start(parameter);

- 807,428
- 183
- 922
- 838
You can use the BackgroundWorker RunWorkerAsync method and pass in your value.

- 48,814
- 22
- 151
- 184
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
int x = 10;
Thread t1 =new Thread(new ParameterizedThreadStart(order1));
t1.IsBackground = true;//i can stope
t1.Start(x);
Thread t2=new Thread(order2);
t2.Priority = ThreadPriority.Highest;
t2.Start();
Console.ReadKey();
}//Main
static void order1(object args)
{
int x = (int)args;
for (int i = 0; i < x; i++)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(i.ToString() + " ");
}
}
static void order2()
{
for (int i = 100; i > 0; i--)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(i.ToString() + " ");
}
}`enter code here`
}
}
I propose using Task<T>
instead of Thread
; it allows multiple parameters and executes really fine.
Here is a working example:
public static void Main()
{
List<Task> tasks = new List<Task>();
Console.WriteLine("Awaiting threads to finished...");
string par1 = "foo";
string par2 = "boo";
int par3 = 3;
for (int i = 0; i < 1000; i++)
{
tasks.Add(Task.Run(() => Calculate(par1, par2, par3)));
}
Task.WaitAll(tasks.ToArray());
Console.WriteLine("All threads finished!");
}
static bool Calculate1(string par1, string par2, int par3)
{
lock(_locker)
{
//...
return true;
}
}
// if need to lock, use this:
private static Object _locker = new Object();"
static bool Calculate2(string par1, string par2, int par3)
{
lock(_locker)
{
//...
return true;
}
}

- 261
- 4
- 12
A very simple and convenient way using lambda expression can be like this:
Thread thread = new Thread( (param) => {
string name = param as string;
// rest of code goes here.
});
thread.Start("MyName");
This way a lambda expression can have parameters and run inline code in a separate thread.

- 410
- 6
- 10
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
int x = 10;
Thread t1 =new Thread(new ParameterizedThreadStart(order1));
t1.Start(x);
Thread t2=new Thread(order2);
t2.Priority = ThreadPriority.Highest;
t2.Start();
Console.ReadKey();
}//Main
static void order1(object args)
{
int x = (int)args;
for (int i = 0; i < x; i++)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(i.ToString() + " ");
}
}
static void order2()
{
for (int i = 100; i > 0; i--)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(i.ToString() + " ");
}
}
}
}
-
Multi threading with C# Threads allow you to develop more efficient applications synchronizing through the shared memory. – Mohammed Hassen Ismaile May 07 '18 at 10:59