views:

899

answers:

4

Hello,

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?

+4  A: 

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
I tried this,it doesn't work. ThreadStart t = new ThreadStart(Startup); << No overload for 'Startup' matches delegate 'System.Threading.ThreadStart
John
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
A: 
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
Just when I write your first line,I get "No overload for 'Startup' matches delegate 'System.Threading.ParameterizedThreadStart"
John
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
you have to change the signiture of the Startup method to accept the ThreadParameter class.....(the class you created with the 2 parameters).
CSharpAtl
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
+10  A: 

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
I get the error when using the "old way",but the lamba expression works perfect. :)
John
Clarified the required Startup method signatures.
Mikko Rantanen
Nice - I just posted an answer below using the "old" way, but didn't realise you could use lambda expressions to create a cleaner thread entry point.
Nathan Ridley
@John: I _strongly_ encourage you to understand _why_ things work and don't work. I get the impression you're copy/pasting, here, and that's doing a major disservice to yourself and your customers.
Greg D
@Mikko: even your "old way" is using C# 3.0 feature of initializing ThreadParams properties :-).
Milan Gardian
@Milan: Good point. I did acknowledge this myself but probably should have mentioned it in the answer too. >.>
Mikko Rantanen
Edited now to use a normal constructor.
Mikko Rantanen
+1  A: 

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