6

I want to pass a function that takes a parameter to the ThreadStart Constructor in C#. But, it seems that this is not possible, as I get a syntax error it I try to do something like this

Thread t1 = new Thread(new ThreadStart(func1(obj1));

where obj1 is an object of type List<string> (say).

If I want a thread to execute this function that takes in an object as a parameter, and I plan to create 2 such threads simultaneously with different parameter values what is the best method to achieve this?

abelenky
  • 63,815
  • 23
  • 109
  • 159
assassin
  • 19,899
  • 10
  • 30
  • 43

9 Answers9

13

If you're using .NET 3.5 or higher, one option is to use a lambda for this:

var myThread = new System.Threading.Thread(() => func1(obj1)); 
Mark Rushakoff
  • 249,864
  • 45
  • 407
  • 398
8

You need ParametrizedThreadStart to pass a parameter to a thread.

Thread t1 = new Thread(new ParametrizedThreadStart(func1);
t1.Start(obj1);
Thomas
  • 174,939
  • 50
  • 355
  • 478
  • Thanks a lot.. this method works.. however, the definition for func1 in this case will have to be void func1(object state) and cannot be void func1(List obj1) why is this the case? – assassin May 12 '10 at 05:05
  • That's how the `ParametrizedThreadStart` delegate type is defined. You'll have to cast the `object` back to `List` inside `func1`. – Thomas May 12 '10 at 06:34
7

You can start a new thread like this:

Thread thread = new Thread(delegate() {
    // Code here.
});
thread.Start();

Inside the anonymous method you have access to the variables that were in scope when the delegate was created.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
3

Try this:

var bar = 0.0;
Thread t = new Thread(() => 
    {
        Foo(bar);
    });
t.IsBackground = true;
t.Start();

Or in your case:

Object obj1 = new Object();
Thread t = new Thread(() => 
    {
        func1(obj1);
    });
t.IsBackground = true;
t.Start();
Kiril
  • 39,672
  • 31
  • 167
  • 226
3

Edit Assassin had trouble getting this code to work, so I have included a complete example console app at the end of this post.



{ // some code
  Thread t1 = new Thread(MyThreadStart);
  t1.Start(theList);
}

void MyThreadStart(object state)
{
  List<string> theList = (List<string>)state;
  //..
}


This is my edit: Below is a complete console app -- the technique really does work:


using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Threading.Thread t = new System.Threading.Thread(MyThreadStart);
            t.Start("Hello");
            System.Console.ReadLine();
        }


        static void MyThreadStart(object state)
        {
            System.Console.WriteLine((string)state);
        }
    }
}


JMarsch
  • 21,484
  • 15
  • 77
  • 125
  • This doesn't work.. i tried it... the ParametrizedThreadStart method suggested by Thomas works. – assassin May 12 '10 at 05:03
  • @assassin I assure you, it does work. I have edited my entry to include a console app that you can paste directly into Visual Studio and run. This syntax has worked since .Net 2.0, and if you replace the "new Thread(MyThreadStart)" with "new Thread(new delegate – JMarsch May 12 '10 at 14:05
3

Is this the effect you're looking for?

        static void Main(string[] args)
    {
        var list = new List<string>(){
            "a","b","c"
        };

        Thread t1 = new Thread(new ParameterizedThreadStart(DoWork));

        t1.Start(list);

        Console.ReadLine();

    }

    public static void DoWork(object stuff)
    {
        foreach (var item in stuff as List<string>)
        {
            Console.WriteLine(item);
        }
    }
Ragoczy
  • 2,907
  • 1
  • 19
  • 17
1
static void func1(object parameter)
{
   // Do stuff here.
}

static void Main(string[] args)
{
  List<string> obj1 = new List<string>();
  Thread t1 = new Thread(func1);
  t1.Start(obj1);
}

It's using a new delegate in .Net 2.0 called ParameterizedThreadStart. You can read about it here.

TheCodeMonk
  • 1,829
  • 1
  • 16
  • 23
0

See ParameterizedThreadStart

KMån
  • 9,896
  • 2
  • 31
  • 41
0

Do you absolutely need to use a Thread object? Or are you just looking for multithreaded processing to happen? A more "modern" approach would be to use an asynchronous delegate as such:

private delegate void FuncDelegate(object obj1);
.
.
.
FuncDelegate func = func1;
IAsyncResult result = func.BeginInvoke(obj1, Completed, func);

// do other stuff
.
.
.

private void Completed(IAsyncResult result)
{
    ((FuncDelegate)result.AsyncState).EndInvoke(result);

    // do other cleanup
}

An even more "modern" method would be to use Tasks in the .NET 4 TPL.

Jesse C. Slicer
  • 19,901
  • 3
  • 68
  • 87