2009-02-03 7 views
7

J'utilise ce code où je suis d'appeler la méthode run d'une liste des classes que je chargé dynamiquement à partir dll:C#: Invoque une méthode avec [type] .InvokeMember() dans un thread séparé

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

le invokeMember invoque la run procédéde chacune des classes dans la liste.

Maintenant comment puis-je invoquer cette méthode run de invokeMember dans un thread séparé? Donc, je vais avoir des threads séparés pour chacune des méthodes invoquées.

Répondre

19

Si vous savez que tous vos types chargés dynamiquement mettre en œuvre Run, pourriez-vous exiger que tous et mettre en œuvre IRunable se débarrasser de la partie de la réflexion?

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 
} 

Sinon, cela fonctionne:

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

Excellent, exactement ce que je cherchais. Et merci pour la mention d'IRunable ... Je l'essaie maintenant. Merci encore. –

+0

Excellent ... Modifié les classes pour utiliser une interface IRunnable comme vous l'avez suggéré. –

2

Jetez un oeil à cet exemple pour une façon de le faire:

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, j'ai juré de rafraîchir cette page avant de cliquer sur soumettre :) –

Questions connexes