2009-02-03 2 views
7

Я использую этот код, где я, вызывающий run метод Списка классов, которые я загружен динамически из библиотеки DLL:C#: Вызвать метод с [Type] .InvokeMember() в отдельном потоке

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); 
} 

invokeMember вызывает метод run каждого из классов в списке.

Теперь как я могу вызвать этот метод из runinvokeMember в отдельную тему? Так что у меня будут отдельные потоки, выполняемые для каждого из вызванных методов.

ответ

19

Если вы знаете, что все ваши динамически загружаемые типы реализуют Run, можете ли вы просто потребовать, чтобы все они реализовали IRunable и избавились от части отражения?

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 
} 

Если нет, то это будет работать:

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(); 
} 
+0

Отлично, именно то, что я искал. И спасибо за упоминание IRunable ... Я пытаюсь это сделать сейчас. Еще раз спасибо. –

+0

Отлично ... Изменены классы, чтобы использовать интерфейс IRunnable, как вы предлагали. –

2

Посмотрите на этот образец для одного из способов сделать это:

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]); 
      } 
     } 
    } 
} 
+0

Bugger, я поклялся, что обновляю эту страницу, прежде чем нанести submit :) –

Смежные вопросы