异步运行时方法调用

时间:2009-11-04 19:35:32

标签: c# reflection delegates invoke methodinfo

我在运行时加载一些程序集并使用Reflections(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 个答案:

答案 0 :(得分:4)

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

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

ThreadPool.QueueUserWorkItem(delegate { methodInf.Invoke(classObj, inputObjs);});

答案 1 :(得分:2)

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

答案 2 :(得分: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

答案 3 :(得分:0)

您是否考虑过使用MethodInvoker(委托,而不是类)而不是尝试创建其他委托?通过使用匿名方法,您可以实现所需。或者我可能会抽烟。但是,基本上,MethodInvoker充当标准的无参数委托,然后在anon方法中,将参数传递给MethodInvoker的无序代码。我已经在WinForms中使用它来做Form.BeginInvoke而无需左右创建委托。如果需要,你可以等待,回复我,今晚我会给你样品代码(我在美国西海岸... GMT -8)。