如何调用(不直接调用)任务的 ContinueWith 方法

本文关键字:调用 方法 ContinueWith 何调用 任务 | 更新日期: 2023-09-27 17:55:26

出于某些业务原因,我无法直接调用服务的方法,因此我编写了如下代码:

class TheService {
    public Task<string> CallMe(string input) {
        return Task.Run(() => {
            return "the result of " + input;
        });
    }
}
//The calling code segment...
//Get the target method's info
MethodInfo mi = typeof(TheService).GetMethod("CallMe");
//Get the target method's return type, yes, it's a Task<string>
ParameterInfo pi = mi.ReturnParameter;
Type taskType = pi.ParameterType;
//Get the service instance.(I new it here for simple reason)
TheService svc = new TheService();
//Invoke the target method and get the Task<string>, however I got only an object (not Task<string>) because I invoke it, not call it directly
object task = mi.Invoke(svc, new[] {"test"});
//How can I make a ContinueWith call here?
//This isn't work! It throws a conversion exception.
//Note: Task<string> is just an example. I wound actually get Task<MyClassA> or Task<MyClassB> here. So, I cannot hard code the conversion. However, I know the Type of Task<T> here. My instinct tells me I should use Invoke again but I don't know how to do.
((Task<object>)task).ContinueWith(a=>{
    Console.WriteLine("The result is " + a.Result);
});

我的问题是如何调用对象的(它实际上是一个任务)继续方法?

或者有什么解决方法?

如何调用(不直接调用)任务<T>的 ContinueWith 方法

您可以使用

基类Task

((Task)task).ContinueWith(a=>{
    Console.WriteLine("The result is " + ((dynamic)a).Result);
});

在完成回调中,((dynamic)a).Result 将在此处键入 dynamic。您可以使用反射投射或询问它。如果你更喜欢反射,你可以首先使用反射而不是dynamic

另一个想法:

static void Run<T>(Task<T> task) {
 ...
}
Run((dynamic)task);

这使用 dynamic 来匹配泛型类型参数,以便调用正常工作。

这是因为您将Task<string>投给了Task<object>

((Task<string>)task).ContinueWith(a => {
    Console.WriteLine("The result is " + a.Result);
});

请记住,具有不同泛型约束的类型不可互换。

如果情况是任务返回类型未知,您可以继续使用反射。

((Task)task).ContinueWith(t =>
{
    var resultProperty = t.GetType().GetProperty("Result");
    var resultObject = resultProperty.GetValue(t);
    Console.WriteLine("The result is " + resultObject);
});