2009-11-04 80 views
2

我在運行時加載一些程序集並使用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); 
    } 

回答

2

只需使用一個包裝調用methodInf.Invoke lambda表達式生成的委託是DelegateMethodInfo

4

您可以使用Delegate.CreateDelegate - 但你需要知道的簽名,以便你有一個適當類型的委託創建。當你基本上只有MethodInfo :(更糟糕的是,沒有相當於Delegate.DynamicInvoke的異步執行

說實話,最簡單的事情是啓動一個新的線程池作業,調用該方法:。

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

難道是準確的說是使用ThreadPool.QueueUserWorkItem在Delegate.CreateDelegate是「動異步執行更高調用堆棧」?無論如何,這對我來說似乎是一個更好的方法。 – 2009-11-04 19:49:21

+0

這是一個相當合理的描述,是的。 – 2009-11-04 19:53:24

0

你有沒有看使用MethodInvoker(委託,而不是類),而不是試圖創建一個額外的委託?通過使用一個匿名的方法,你可能會得到你需要的東西。或者我可能會抽菸。但是,基本上,MethodInvoker在anon方法中充當標準無參數委託,將您的參數傳遞給MethodInvoker的匿名代碼。我在WinForms中用它來做Form.BeginInvoke,而不需要左右創建代表。如果需要,你可以等待,回覆我,我會在今晚給你示例代碼(我在美國西海岸...格林威治標準時間-8)。

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