【问题标题】:C# : Invoke a method with [Type].InvokeMember() in a separate ThreadC#:在单独的线程中使用 [Type].InvokeMember() 调用方法
【发布时间】:2009-02-03 00:00:18
【问题描述】:

我正在使用这段代码来调用我从 dll 动态加载的类列表的 run 方法:

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 方法。

现在如何在单独的线程中从invokeMember 调用此run 方法?这样我就可以为每个调用的方法运行单独的线程。

【问题讨论】:

    标签: c# .net multithreading reflection


    【解决方案1】:

    如果您知道所有动态加载的类型都实现了 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();
    }
    

    【讨论】:

    • 非常好,正是我想要的。感谢您提到 IRunable...我现在正在尝试。再次感谢。
    • 优秀...更改了类以使用您建议的 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]);
                }
            }
        }
    }
    

    【讨论】:

    • 混蛋,我发誓我在点击提交之前刷新了这个页面 :)
    猜你喜欢
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-29
    • 1970-01-01
    相关资源
    最近更新 更多