2009-11-04 2 views
2

런타임에 어셈블리를로드하고 Reflections (MethodInfo.Invoke)를 사용하여 메서드를 호출합니다.비동기 런타임 메서드 호출

이제 이러한 호출을 비동기 적으로 만들고 싶습니다. 그래서 Delegate.BeginInvoke()를 사용하려고합니다. 하지만 런타임에 함수 이름을 제공하여 대리인 인스턴스를 만드는 방법을 모르겠습니다. (모든 예제에서는 컴파일 타임에 인스턴스가 delegate 된 인스턴스 타겟을가집니다.) 호출 할 메소드가 포함 된 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에 대한 호출을 래핑하는 람다 식을 사용하는 결과로 위임 유형 DelegateMethodInfo이다

4

당신은 Delegate.CreateDelegate을 사용할 수 있습니다 -하지만 당신이 만들 수있는 위임의 적절한 유형을 가지고 있도록 서명을 알아야합니다. 즉, 비동기 실행을위한 Delegate.DynamicInvoke의 동등한가 없습니다, 당신은 기본적으로 그냥 MethodInfo :(더 나쁜있어 때 약간 까다로운.

것은 솔직히 말해서, 가장 간단한 것은 메소드를 호출 새로운 스레드 풀 작업을 시작하는 것입니다 :..

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

그것이 정확겠습니까 사용할 수 있습니까? 어쨌든 나에게 더 나은 접근법처럼 보입니다. –

+0

그건 꽤 합리적인 설명, 예. –

0

당신은 MethodInvoker (대리인이 아닌 클래스) 및하지를 사용하여 봤어 추가 위임자를 만들려고합니까? 익명의 방법을 사용하면 필요한 것을 제거 할 수 있습니다. 또는 나는 균열을 피우고 있을지도 모른다. 그러나 기본적으로 MethodInvoker는 매개 변수없는 대리자로 사용되며 anon 메서드에서는 매개 변수를 MethodInvoker의 코드에 전달합니다. WinForms에서 Form.BeginInvoke를 사용하여 왼쪽 및 오른쪽 대리자를 만들지 않아도되었습니다. 필요가 있고 기다릴 수 있다면 나에게 응답하면 오늘 밤에 샘플 코드를 얻을 것이다 (나는 미국 서부 해안에 ... GMT-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(); 
} 

그것은 무엇 MethodInfo.Invoke의 서명과 일치 유형 Func<object, object[], object>의 새로운 변수를 만드는 일입니다. 그런 다음 개체에 대한 실제 호출 메서드에 대한 참조를 가져오고 해당 참조를 변수에 고정시킵니다.

Func<>는 대리자 형식이기 때문에, 당신은 다음 Delegate.CreateDelegate 이상 ThreadPool.QueueUserWorkItem 사용 "이 호출 스택에 높은 비동기 실행을 이동하는"것을 말 BeginInvoke