views:

93

answers:

3

Hi how do i call System.Reflection.MethodInfo.Invoke() with paramters with threads.

For instance..

Say I have a method that allows you to pass in a string that represents a class name and calls corresponding class method dynamically , now i want to call this Methodinfo.invoke with threads ,I have no idea how to do this since i am calling invoke with paramter . Code snippet given meblow . Thank you for your help

Type classType = objAssembly.GetType("MyClassName");
object obj = Activator.CreateInstance(classType)
bject[] _objval = new object[3]; 
object[] parameters = new object[] { _objval };
MethodInfo mi = classType.GetMethod("MyMethod");
mi.Invoke(obj, parameters);  // <---**How do i call this with threads.. ????**
+5  A: 

Since you're wanting to create a new thread with System.Threading.Thread rather than make the call on an existing UI thread or threadpool thread, first thing to notice is that with System.Threading.Thread you can use either a ThreadStart or ParameterizedThreadStart delegate.

You do want parameters to your thread's main method, but ParameterizedThreadStart only allows an object, which forces you to cast it to the required type. So we'll just use a closure to get all the arguments passed across in a type-safe way.

public void InvokeOnNewThread(this MethodInfo mi, object target, params object[] parameters)
{
     ThreadStart threadMain = delegate () { mi.Invoke(target, parameters); };
     new System.Threading.Thread(threadMain).Start();
}

Example usage:

mi.InvokeOnNewThread(obj, parameters);

If you're working with .NET 2.0, then take out the keyword this from the parameter list and call like:

InvokeOnNewThread(mi, obj, parameters);

This will discard any return value, but so did the unthreaded example in your question. If you need the return value leave a comment.

Ben Voigt
+1 for readable code.
Danny Chen
Thats perfect my dear friend . Thank you very much .can u explain me what ThreadStart threadMain = delegate () this does . Only from last week i startedd using C# after beiong c++ programmer for 2 years . I know delegate is quite like function pointer ...
ITion
You already were using a delegate in your code: `new Thread(pts);` But that delegate references a named method. Here I am using an anonymous method, created with the `delegate` keyword, in order to capture variables. This is a C# feature, not part of the .NET runtime. The C# compiler will actually create a class (with a very weird name illegal to use in C# code) that stores the captured variables `mi`, `target`, and `parameters` and it will put the code in a method in that class. Then when the method runs, it can read the parameters values using its `this` pointer.
Ben Voigt
I strongly suggest that you read Jon Skeet's introduction to closures here http://csharpindepth.com/Articles/Chapter5/Closures.aspx His book **C# in Depth** is also highly recommended.
Ben Voigt
Thank you very much for your explanation .
ITion
+1  A: 

You can start a thread with an anonymous method:

Thread myThread = new Thread(delegate() {
    object obj = Activator.CreateInstance(typeof(MyClassName));

    object[] _objval = new object[3]; 
    object[] parameters = new object[] { _objval };
    MethodInfo mi = classType.GetMethod("MyMethod");
    mi.Invoke(obj, parameters); 
});
myThread.Start();

The code inside the delegate() { ... } is an anonymous method that is executed on the new thread.

SLaks
A: 

Just a suggestion, why not use .Net 4.0 Framework it has an easier threading implementation. Just use Parallel.For, Parallel.ForEach() or Parallel.Invoke(). Some further explanation here -> http://anyrest.wordpress.com/2010/09/09/parallel-programming-easier-than-ever-using-net-framework-4/

Raymund
Since `Parallel.Invoke` accepts `Action` delegates which can't accept arguments, this doesn't really answer the question. Letting the Parallel Tasks library manage a threadpool is a good alternative to `new Thread` of course, but the OP didn't seem to want to use a threadpool.
Ben Voigt