views:

1365

answers:

6

I am using multithreading in my C# code as follow:

Thread startThread;

public void NewThread()
{
   ThreadStart starter = delegate { foo(); };
   startThread = new Thread(starter);
   startThread.Start();
}

private void foo()
{
   //do some work
}

And then in my application I call NewThread()to run the new thread.

But now I am having lots of threads on each class and each one has a NewThread() for itself, I was thinking of moving this to a static Util class and pass it the function name each time I want a new thread on that function.

Do you know how this the best way of doing it, if yes how can I pass the function name as a parameter to it?

A: 

Take a look at the following article on Codeproject "Poor Man's Parallel.ForEach Iterator". I think that's exactly what you are searching for. Very easy to use.

For something more powerful also take a look at Power Threading Library.

Alexander
+4  A: 

Well, since the method is private, does it make sense for the caller to know the method name? If it was public, you could pass the method in:

public void NewThread(Action task)
{
   ThreadStart starter = delegate { task(); };
   startThread = new Thread(starter);
   startThread.Name = task.Method.Name;
   startSpoolerThread.Start();
}

public void foo()
{
   //do some work
}

NewThread(obj.foo);

However, for a private method, I suspect an enum/switch is the best option...

NewThread(TasktType.Foo);

Alternatively, you can get the method via reflection...

public void NewThread(string name)
{
    MethodInfo method = GetType().GetMethod(name,
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
        null, Type.EmptyTypes, null);
    ThreadStart starter = delegate { method.Invoke(this, null); };
    // etc (note: no point using Delegate.CreateDelegate for a 1-call usage
Marc Gravell
+1  A: 

I'd encourage you to also consider looking at the CTP of Parallel Extensions Task APIs; you don't mention why you need a thread, but they've automated much of this here's a link to their blog

Rick
+3  A: 

Unless there's a specific reason you're explicitly creating threads, why not use the Threadpool? The Threadpool.QueueUserWorkItem method takes a delegate as the unit of work to perform. The delegate is a specific type but you can wrap your own delegate call within it as you do in your example. Unless you need fine control or cancellation, in general it's better to use the thread pool rather than spinning up threads yourself.

Fake Jim
A: 

Alternatively, if you are doing a Win.Forms or similar GUI-based application I'd recommend using BackgroundWorker. It takes care of marshalling for most thread-related events for you and is also much less complex to abort (if that is something you need to do).

Hans Løken
A: 

Delegates already provide a method to execute them asynchronously. For example:

delegate void dowork();
private static void WorkDone(IAsyncResult result)
{
   ((dowork)result.AsyncState).EndInvoke(result);
    // this function is called when the delegate completes
}
public void Start()
{
    dowork dw = delegate {// code in this block has it's own thread };
    dw.BeginInvoke(WorkDone, null);
}

So in order to pass a function pointer to anything else, you need only create a delegate with the correct signature (in this case I used an anonymous method, but you can use any function with the correct signature) and call it's BeginInvoke method, passing a function that will get called when it's done.. that function has to then call EndInvoke on the original delegate, which is passed to the WorkDone function in the result parameter.

Mystere Man