2009-02-03 13 views
7

używam tego kodu, gdzie jestem wywołanie metody z listy klas I załadowany dynamicznie DLL run:C#: Wywołaj metodę z [Type] .InvokeMember() w osobnym wątku

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

Metoda invokeMember wywołuje metodę run każdej z klas na liście.

Teraz Jak mogę wywołać tę metodę run z invokeMember w osobnym wątku? Tak, że będę mieć oddzielne wątki uruchomione dla każdej z przywołanych metod.

Odpowiedz

19

Jeśli wiesz, że wszystkie Twoje dynamicznie ładowane typy implementują Run, czy możesz po prostu wymagać, aby wszystkie implementowały protokół IRunable i pozbyły się części Reflect?

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 
} 

Jeśli nie, to będzie działać:

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

Doskonałe, dokładnie to, czego szukałem. I dziękuję za wzmiankę o IRunable ... Próbuję tego teraz. Jeszcze raz dziękuję. –

+0

Doskonała ... Zmieniono klasy, aby korzystać z interfejsu IRunnable, tak jak sugerowałeś. –

2

Zapraszamy do obejrzenia tej próbki na jeden sposób to zrobić:

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, przysiągłem, że odświeżam tę stronę, zanim kliknę przycisk submit :) –

Powiązane problemy