我在运行时加载一些程序集并使用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);
}
答案 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)。