67

The method below is what I want to be done in that thread:

public void Startup(int port,string path)
{
    Run(path);
    CRCCheck2();
    CRCCheck1();
    InitializeCodeCave((ushort)port);
}

I tried what I could find googling,but nothing worked

public void Test(int port,string path)
{
    Thread t = new Thread(Startup(port,path));
}

public void TestA(int port,string path)
{
    Thread t = new Thread(Startup);
    t.Start (port,path);
}

Both don't compile,how to do that?

shytikov
  • 9,155
  • 8
  • 56
  • 103
Ivan Prodanov
  • 34,634
  • 78
  • 176
  • 248

5 Answers5

84

The following ways work.

// The old way of using ParameterizedThreadStart. This requires a
// method which takes ONE object as the parameter so you need to
// encapsulate the parameters inside one object.
Thread t = new Thread(new ParameterizedThreadStart(StartupA));
t.Start(new MyThreadParams(path, port));

// You can also use an anonymous delegate to do this.
Thread t2 = new Thread(delegate()
{
    StartupB(port, path);
});
t2.Start();

// Or lambda expressions if you are using C# 3.0
Thread t3 = new Thread(() => StartupB(port, path));
t3.Start();

The Startup methods have following signature for these examples.

public void StartupA(object parameters);

public void StartupB(int port, string path);
Mikko Rantanen
  • 7,884
  • 2
  • 32
  • 47
23

Update The currently suggested way to start a Task is simply using Task.Run()

Task.Run(() => foo());

Note that this method is described as the best way to start a task see here

Previous answer

I like the Task Factory from System.Threading.Tasks. You can do something like this:

Task.Factory.StartNew(() => 
{
    // Whatever code you want in your thread
});

Note that the task factory gives you additional convenience options like ContinueWith:

Task.Factory.StartNew(() => {}).ContinueWith((result) => 
{
    // Whatever code should be executed after the newly started thread.
});

Also note that a task is a slightly different concept than threads. They nicely fit with the async/await keywords, see here.

anhoppe
  • 4,287
  • 3
  • 46
  • 58
10

The method that you want to run must be a ThreadStart Delegate. Please consult the Thread documentation on MSDN. Note that you can sort of create your two-parameter start with a closure. Something like:

var t = new Thread(() => Startup(port, path));

Note that you may want to revisit your method accessibility. If I saw a class starting a thread on its own public method in this manner, I'd be a little surprised.

Greg D
  • 43,259
  • 14
  • 84
  • 117
  • I tried this,it doesn't work. ThreadStart t = new ThreadStart(Startup); << No overload for 'Startup' matches delegate 'System.Threading.ThreadStart – Ivan Prodanov May 01 '09 at 13:02
  • Startup takes two parameters. If you check the docs I linked, ThreadStart takes no parameters. We can cheat with a closure to make it look like two (in 3.5) , or we can use ParameterizedThreadStart and bundle the two parameters up into an object (pre 3.5). – Greg D May 01 '09 at 13:04
4

Your example fails because Thread methods take either one or zero arguments. To create a thread without passing arguments, your code looks like this:

void Start()
{
    // do stuff
}

void Test()
{
    new Thread(new ThreadStart(Start)).Start();
}

If you want to pass data to the thread, you need to encapsulate your data into a single object, whether that is a custom class of your own design, or a dictionary object or something else. You then need to use the ParameterizedThreadStart delegate, like so:

void Start(object data)
{
    MyClass myData = (MyClass)myData;
    // do stuff
}

void Test(MyClass data)
{
    new Thread(new ParameterizedThreadStart(Start)).Start(data);
}
Nathan Ridley
  • 33,766
  • 35
  • 123
  • 197
3
public class ThreadParameter
        {
            public int Port { get; set; }
            public string Path { get; set; }
        }


Thread t = new Thread(new ParameterizedThreadStart(Startup));
t.Start(new ThreadParameter() { Port = port, Path = path});

Create an object with the port and path objects and pass it to the Startup method.

CSharpAtl
  • 7,374
  • 8
  • 39
  • 53
  • Just when I write your first line,I get "No overload for 'Startup' matches delegate 'System.Threading.ParameterizedThreadStart" – Ivan Prodanov May 01 '09 at 13:05
  • The startup needs to be "void Startup(object parameters)". You cannot use "void Startup(ThreadParameter parameters)" as you cannot pass an object to that one. You can cast the object parameters to ThreadParameter inside the Startup. – Mikko Rantanen May 01 '09 at 13:10
  • you have to change the signiture of the Startup method to accept the ThreadParameter class.....(the class you created with the 2 parameters). – CSharpAtl May 01 '09 at 13:10
  • 1
    you actually have to make the signature of Startup to take in an object and when you get in the method cast it to the ThreadParameter object. – CSharpAtl May 01 '09 at 13:13