Question

Je suis le chargement des assemblages à l'exécution et l'invocation des méthodes de les utiliser Reflections (MethodInfo.Invoke).

Maintenant, je veux faire ces appels asynchrones. Donc, je pense à l'aide Delegate.BeginInvoke (). Mais je ne suis pas sûr de savoir comment créer une occurrence de délégué en fournissant le nom de la fonction lors de l'exécution. (Tous les exemples que je vois que vous avez la cible d'instance de délégué résolu au moment de la compilation elle-même.) J'ai un objet MethodInfo contenant la méthode à invoquer. Est-il possible de le faire?

   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);
    }
Était-ce utile?

La solution

Il suffit d'utiliser une expression lambda qui enveloppe l'appel à methodInf.Invoke. Le délégué résultant est de type DelegateMethodInfo.

Autres conseils

Vous pouvez utiliser Delegate.CreateDelegate - mais vous aurez besoin de connaître la signature de sorte que vous avez un type approprié de délégué pour créer. C'est un peu difficile quand vous avez fondamentalement juste obtenu le MethodInfo :( Pire encore, il n'y a pas d'équivalent de Delegate.DynamicInvoke pour l'exécution asynchrone.

Pour être honnête, la chose la plus simple serait de commencer un nouveau travail de pool de threads qui a invoqué la méthode:

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

Ceci est similaire aux autres réponses, mais vous pouvez créer une nouvelle Func et affecter la méthode methodInf.Invoke à elle. Voici un exemple

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

Qu'est-ce qu'il fait est la création d'une nouvelle variable de type Func<object, object[], object>, qui correspond à la signature de MethodInfo.Invoke. Il obtient alors une référence à la méthode Invoke réelle sur votre objet et colle cette référence dans la variable.

Parce que Func<> est un type de délégué, vous pouvez ensuite utiliser BeginInvoke

Avez-vous envisagé d'utiliser MethodInvoker (Le délégué, pas la classe) et ne pas essayer de créer un délégué supplémentaire? En utilisant une méthode anonyme avec cela, vous pourrez peut-être retirer ce que vous avez besoin. Ou peut-être que je fissure fumer. Mais, au fond, MethodInvoker agit en tant que délégué standard, puis dans la parameterless méthode Anon, vous passez vos paramètres au code de anonmous MethodInvoker. Je l'ai utilisé en WinForms faire Form.BeginInvoke sans avoir besoin de créer des délégués gauche et à droite. Si besoin et vous pouvez attendre, me répondre et je vais vous donner un exemple de code ce soir (je suis sur la côte ouest des États-Unis ... GMT -8).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top