Asynchronous runtime method invocation
I am loading some assemblies at run time and invoking methods on them using Reflections (MethodInfo.Invoke).
Now I want to make these calls asynchronous. So I am thinking of using Delegate.BeginInvoke(). But I am not sure how to create delegate instance by providing function name at run-time. (All examples I see have delegate instance target resolved at compile time itself.) I have a MethodInfo object containing the method to be invoked. Is there a way to do this?
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);
}
You can use Delegate.CreateDelegate
- but you'll need to know the signature so that you've got an appropriate type of delegate to create. That's slightly tricky when you've basically just got the MethodInfo
:( Even worse, there's no equivalent of Delegate.DynamicInvoke
for asynchronous execution.
To be honest, the simplest thing would be to start a new thread pool job which invoked the method:
ThreadPool.QueueUserWorkItem(delegate { methodInf.Invoke(classObj, inputObjs);});
Just use a lambda expression that wraps the call to methodInf.Invoke. The resulting delegate is of type DelegateMethodInfo
.
This is similar to the other answers, but you can create a new Func
and assign the methodInf.Invoke
method to it. Here's an example
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();
}
What it's doing is creating a new variable of type Func<object, object[], object>
, which matches the signature of MethodInfo.Invoke
. It then gets a reference to the actual invoke method on your object, and sticks that reference in the variable.
Because Func<>
is a delegate type, you can then use BeginInvoke
Have you looked at using MethodInvoker (The delegate, not the class) and not trying to create an additional delegate? By using an anonymous method with this, you may be able to pull off what you need. Or I may be smoking crack. But, basically, MethodInvoker acts as a standard parameterless delegate then in the anon method, you pass your parameters to MethodInvoker's anonmous code. I've used it in WinForms to do Form.BeginInvoke without needing to create delegates left and right. If need to and you can wait, respond to me and I'll get you sample code tonight (I'm on US West Coast... GMT -8).
精彩评论