Consider the following code :
namespace MyThreads
{
public class HisThread
{
public int Thread2(int start, int end, int[] arr)
{
int sum = 0;
// foreach (int i in arr)
for (int i = start; i <= end; i++)
{
sum += arr[i];
}
return sum;
}
}
public class MyThread
{
public void Thread1()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("Hello world " + i);
Thread.Sleep(1);
}
}
}
public class Test
{
public static void Main()
{
int[] arr = new int[30];
for (int i = 0; i < 30; i++ )
{
arr[i] = i;
}
Console.WriteLine("Before start thread");
// thread 1 - without params
MyThread thr = new MyThread();
Thread tid1 = new Thread(new ThreadStart(thr.Thread1)); // this one is OK
tid1.Start();
// thread 2 - with params
HisThread thr2 = new HisThread();
Thread tid2 = new Thread(new ParameterizedThreadStart(thr2.Thread2));
}
}
}
The first thread compiles fine (with no arguments) but the second thread produces
Error 1 No overload for 'Thread2' matches delegate
Any idea how to fix that ?
Thanks
ParameterizedThreadStart delegate requires method which accepts single parameter of object
type:
public delegate void ParameterizedThreadStart(object obj)
I.e. your method should be
public class HisThread
{
public void Thread2(object obj)
{
// ...
}
}
Also there is method Thread.Start which accepts parameter:
// thread 2 - with params
HisThread thr2 = new HisThread();
Thread tid2 = new Thread(new ParameterizedThreadStart(thr2.Thread2));
tid2.Start(parameter);
If you are using .NET 4.5 you can use tasks instead:
Task<int>.Run(() => thr2.Thread2(start, end, array))
The problem with that code is that ParameterizedThreadStart
is a delegate type, which means it is tied to a specific method signature -- in particular, that signature is void method(object)
. Your method Thread2
does not match that signature, hence the compiler error.
So how to solve it? It depends really.
ParameterizedThreadStart
has that signature because it's the most generic approach ever. The idea behind it is that you can pass an object of some custom type that contains all the state your function needs, like this:
class Params
{
public int Start { get; set; }
public int End { get; set; }
public int[] Array { get; set; }
}
var p = new Params { 0, 0, new int[0] };
var t = new Thread(thr2.Thread2);
t.Start(p);
public int Thread2(object param)
{
var p = (Params)param;
// and now get your arguments as p.Start etc.
}
While this works, it's unwieldy and forces you to abandon the most natural signature for Thread2
. But you can do better by interposing an anonymous function to do the unpacking of arguments:
int start = 0, end = 0;
var arr = new int[0];
var t = new Thread(() => thr2.Thread2(start, end, arr));
If you choose to do this you have to be mindful of the fact that due to the mechanism the compiler uses to pass the arguments to the thread method, changing their values after t
is defined but before it is started will make Thread2
see the changed values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With