2

我在运行时加载一些程序集并使用反射(MethodInfo.Invoke)在它们上调用方法。

现在我想让这些调用异步。所以我正在考虑使用 Delegate.BeginInvoke()。但我不确定如何通过在运行时提供函数名称来创建委托实例。(我看到的所有示例都在编译时解析了委托实例目标。)我有一个 MethodInfo 对象,其中包含要调用的方法。有没有办法做到这一点?

   public void Invocation(Object[] inputObjs)
    {
        public delegate string DelegateMethodInfo(int num);

        Assembly assm = Assembly.Load(assemblyName);
        Type type = assm.GetType(className);
        Type[] ctorParams = new Type[0];
        Object[] objs = new Object[0];

        ConstructorInfo ctorInf = type.GetConstructor(ctorParams);
        Object classObj = ctorInf.Invoke(objs);
        MethodInfo methodInf = type.GetMethod(methodName);

        // Need asynchronous invocation.
        //Object retObj = methodInf.Invoke(classObj, inputObjs);

        DelegateMethodInfo del = new DelegateMethodInfo(???); // How to instantiate the delegate???
        del.BeginInvoke((int)inputObjs[0], null, null);
    }
4

4 回答 4

4

您可以使用Delegate.CreateDelegate- 但您需要知道签名,以便您可以创建适当类型的委托。当您基本上刚刚获得MethodInfo:( 时,这有点棘手,更糟糕的是,没有Delegate.DynamicInvoke异步执行的等价物。

老实说,最简单的事情是启动一个调用该方法的新线程池作业:

ThreadPool.QueueUserWorkItem(delegate { methodInf.Invoke(classObj, inputObjs);});
于 2009-11-04T19:39:21.680 回答
2

只需使用包装对 methodInf.Invoke 的调用的 lambda 表达式。生成的委托是类型DelegateMethodInfo

于 2009-11-04T19:40:33.550 回答
1

这类似于其他答案,但您可以创建一个新Func的并将methodInf.Invoke方法分配给它。这是一个例子

class Other
{
    public void Stuff()
    { Console.WriteLine("stuff"); }
}

static void Main(string[] args)
{
    var constructor = typeof(Other).GetConstructor(new Type[0]);
    var obj = constructor.Invoke(null);

    var method = typeof(Other).GetMethods().First();
    Func<object, object[], object> delegate = method.Invoke;
    delegate.BeginInvoke(obj, null, null, null);

    Console.ReadLine();
}

它所做的是创建一个新的类型变量Func<object, object[], object>,它与MethodInfo.Invoke. 然后它获取对对象上实际调用方法的引用,并将该引用粘贴在变量中。

因为Func<>是委托类型,所以你可以使用BeginInvoke

于 2009-11-04T19:47:24.793 回答
0

您是否考虑过使用 MethodInvoker(委托,而不是类)而不是尝试创建额外的委托?通过使用匿名方法,您可以完成您需要的内容。或者我可能正在吸烟。但是,基本上,MethodInvoker 充当标准的无参数委托,然后在 anon 方法中,您将参数传递给 MethodInvoker 的匿名代码。我在 WinForms 中使用它来执行 Form.BeginInvoke 而无需左右创建委托。如果需要,您可以等待,回复我,今晚我会给您提供示例代码(我在美国西海岸... GMT -8)。

于 2009-11-04T19:46:46.160 回答