异步运行时方法调用

发布于 2024-08-10 05:36:43 字数 960 浏览 9 评论 0原文

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

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);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

请恋爱 2024-08-17 05:36:43

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

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

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

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);});
眼波传意 2024-08-17 05:36:43

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

Just use a lambda expression that wraps the call to methodInf.Invoke. The resulting delegate is of type DelegateMethodInfo.

决绝 2024-08-17 05:36:43

这与其他答案类似,但您可以创建一个新的 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 类型的新变量,该变量与 MethodInfo.Invoke 的签名相匹配。然后,它获取对对象上实际调用方法的引用,并将该引用粘贴到变量中。

由于 Func<> 是委托类型,因此您可以使用 BeginInvoke

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

暖风昔人 2024-08-17 05:36:43

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

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文