views:

6610

answers:

3

I am using this code where I am invoking the run method of a List of classes that I loaded dynamically from dlls:

for (int i = 0; i < robotList.Count; i++)
{
    Type t = robotList[i]; //robotList is a List<Type>
    object o = Activator.CreateInstance(t);
    t.InvokeMember("run", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, null);
}

The invokeMember is invoking the run methodof each of the classes in the list.

Now how can I invoke this run method from invokeMember in a separate Thread ? So that I'll have separate threads running for each of the invoked methods.

+7  A: 

If you know that all your dynamically loaded types implement Run, could you just require they all implement IRunable and get rid of the reflection part?

Type t = robotList[i];
IRunable o = Activator.CreateInstance(t) as IRunable;
if (o != null)
{
    o.Run(); //do this in another thread of course, see below
}

If not, this will work:

for (int i = 0; i < robotList.Count; i++)
{
    Type t = robotList[i];
    object o = Activator.CreateInstance(t);
    Thread thread = new Thread(delegate()
    {
        t.InvokeMember("Run", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, null);
    });
    thread.Start();
}
Rex M
Excellent, exactly what I was looking for. And thanks for the mention of IRunable...I am trying it out now.Thanks again.
Andreas Grech
Excellent...Changed the classes to use an IRunnable interface like you suggested.
Andreas Grech
+1  A: 

Have a look at this sample for one way of doing it:

using System;
using System.Threading;
using System.Reflection;
using System.Collections.Generic;

namespace Obfuscation
{
    public class Program
    {
        static Type[] robotArray = new Type[] { typeof(Program) };
        static List<Type> robotList = new List<Type>(robotArray);

        internal void Run()
        {
            Console.WriteLine("Do stuff here");
        }

        internal static void RunInstance(object threadParam)
        {
            Type t = (Type)threadParam;
            object o = Activator.CreateInstance((Type)t);
            t.InvokeMember("Run", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic, null, o, null);
        }

        public static void Main(string[] args)
        {
            for (int i = 0; i < robotList.Count; i++)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(RunInstance), robotList[i]);
            }
        }
    }
}
OJ
Bugger, I swore I refresh this page before hitting submit :)
OJ
A: 

Hi,

I was wandering in the answer provided above:

   Thread thread = new Thread(delegate()
    {
        t.InvokeMember("Run", BindingFlags.Default | BindingFlags.InvokeMethod, null, o, null);
    });

If we assume for a second that "run" returns a bool, for instance. How do you get back that bool value from the thread?

Thanks

armaniake
You could use a BackgroundWorker, which creates an event in your main thread once your subthread has finished. As a general note: You should create a new StackOverflow question (button "Ask Question" in the upper right-hand corner) for each new question.
Heinzi