簡體   English   中英

使用反射,調用通用異步方法

[英]Using Reflection, Invoke Generic Async Method

與已知的編譯時類型一起使用時,我有一個類似於以下的模式:

// given a method like this...
public RSType ComputeSomething(RQType rq) {
    RSType rs = new RSType();
    // do something to rs here, based on rq...
    return rs;
}

// I'm able to do create an event handler like this
eventHandlers.RequestResponseAsync<RQType, RSType>(rq =>
    Task.Factory.StartNew(() =>
    {
        return ComputeSomething(rq);
    }));

現在,我正在嘗試使用反射,以便可以在運行時找到ComputeSomething之類的函數,然后在適當時調用RequestResponseAsync。

有一個非異步版本,我已經可以使用了。 例如,給定相同的ComputeSomething:

// get the handler method, and types
var handlerType = Assembly.LoadFrom("SomeAssembly").GetType("SomeNameSpace.SomeClass");
var handlerMethod = handlerType.GetMethod("ComputeSomething");
var handlerParamType = handlerMethod.GetParameters().FirstOrDefault().ParameterType;
var handlerReturnType = handlerMethod.ReturnType;

// get MethodInfo for a generic RequestResponseAsync
var respond = eventHandlers.GetType().GetMethod("RequestResponseAsync");
var genericRespond = respond.MakeGenericMethod(new Type[] { handlerParamType, handlerReturnType });

// create a delegate to pass to the invocation
var delegateType = typeof(Func<,>).MakeGenericType(handlerParamType, handlerReturnType);
var del = Delegate.CreateDelegate(delegateType, handlerMethod);

// invoke the method
genericRespond.Invoke(eventHandlers, new[] { del });

但是我的大腦很小,無法弄清楚如何將其帶入下一個異步級別。

有人可以告訴我嗎?

我不確定是否有人建議這樣做,但是我想結束循環。

這是我所做的,似乎可行。

我創建了一個通用的Func工廠函數,然后通過反射對其進行調用。

Func<RQ,Task<RS>> RqRsAsyncHandler<RQ,RS>(Func<RQ,RS> handler) 
{
    return (RQ rq) =>
    {
        return Task.Factory.StartNew(() =>
        {
            return handler(rq);
        });
    };
}

然后,我基本上像以前一樣進行操作,但是,傳入函數工廠創建的Func。

// get a delegate for the actual handler
var delegateType = typeof(Func<,>).MakeGenericType(handlerParamType, handlerReturnType);
var del = Delegate.CreateDelegate(delegateType, handlerMethod);

// get a Func that wraps that handler in a tracer handler
var RqRsAsyncHandlerMethodInfo = typeof(Container).GetMethod("RqRsAsyncHandler");
var RqRsAsyncHandlerMethodInfoGeneric = RqRsAsyncHandlerMethodInfo.MakeGenericMethod(handlerParamType, handlerReturnType);
var wrapperFunc = RqRsAsyncHandlereMethodInfoGeneric.Invoke(null, new object[] { del });

// get the eventHandlers method
MethodInfo respondMethod = typeof(EventHandlers).GetMethod("RespondAsync");
MethodInfo genericRespondMethod = respondMethod.MakeGenericMethod(new[] { handlerParamType, handlerReturnType });

// invoke the Bus method
genericRespondMethod.Invoke(eventHandlers , new[] { wrapperFunc });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM