4

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

3
  • 2
    ParameterizedThreadStart only works with parameters of type "object". You would have to change the method signature of Thread2 to use only parameters of type "object" Commented Dec 6, 2013 at 13:27
  • If you search passing parameters using threads you ll get too many answers. Commented Dec 6, 2013 at 13:28
  • This would be very helpful: albahari.com/threading Commented Dec 6, 2013 at 13:29

7 Answers 7

3

ParameterizedThreadStart delegate requires method which accepts single parameter of objecttype:

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))
Sign up to request clarification or add additional context in comments.

2 Comments

@SriramSakthivel just copy-paste issue, already fixed, thanks
Yes, That happens a lot :)
2

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.

Comments

2
Thread thr2 = new Thread(() => thr2.Thread2(0, 1, arr));

It can have some side-effects, though, if you tweak your variables immediately after calling this, since you're effectively passing the variables in by reference.

Comments

2

Try this:

Thread thread = new Thread(() => new HisThread().Thread2(0, 3, new int[] { 1, 2, 3, 4 }));

And if you are in 2.0:

Thread thread = new Thread(delegate() { new HisThread().Thread2(0, 3, new int[] { 1, 2, 3, 4 }); });

Comments

1

This may helps:

class MyParameter
{
    public int Start, End; //Use Properties for these
    public int[] Array;    //Use Properties for this
}

Then:

 // thread 2 - with params
 HisThread thr2 = new HisThread();
 Thread tid2 = new Thread(new ParameterizedThreadStart(p =>
 {
     var temp = (MyParameter)p;
     thr2.Thread2(temp.Start, temp.End, temp.Array);
 }));

 tid2.Start(new Parameter(1, 10, yourArray));

Comments

1

Why that doesn't compile?

Because your delegate doesn't match the required signature.

Any idea how to fix that ?

Solution1: Create your own type and pass data

public class MyClass
{
    public int start {get;set;};
    public int end {get;set;};
    public int[] arr {get;set;};
}

public void Thread2(object parameter)
{
    MyClass obj = (MyClass)parameter;
    //Make use of obj
}

HisThread thr2 = new HisThread();
Thread tid2 = new Thread(new ParameterizedThreadStart(thr2.Thread2));
tid2.Start(new MyClass{...});

Solution2: Just use a lambda

HisThread thr2 = new HisThread();
Thread tid2 = new Thread(() => thr2.Thread2(param1,param2,param3));
tid2.Start();

Comments

0

Easiest is to delegate like so...

    ThreadStart ts = delegate
    {
          bool moreWork = DoWork("param1", "param2", "param3");
          if (moreWork) 
          {
              DoMoreWork("param1", "param2");
          }
    };
    new Thread(ts).Start();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.