2016-07-06 21 views
0

对于某些业务的原因,我不能调用服务的直接方法,所以我写了这样的代码:如何调用(不直接调用)的任务<T> ContinueWith方法?

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

我的问题是如何调用该对象的(这实际上是一个任务)ContinueWith方法?

或任何解决方法吗?

+0

什么转换例外居然说? –

+0

他不会静态地知道类型参数将会是什么。 – usr

回答

4

您可以使用基类Task

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

里面完成回调((dynamic)a).Resultdynamic类型的在这里。你可以使用反射来投射或者询问它。如果你更喜欢这个,你可以首先使用反射,而不是dynamic

另一个想法:

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

Run((dynamic)task); 

这使用dynamic相匹配的泛型类型参数,以便电话工程。

+1

令人惊叹!有用! – guogangj

0

那是因为你投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); 
}); 
+1

“请记住,具有不同通用约束的类型不可互换”对于使用['out' keyword](https://msdn.microsoft.com/en-us/library/dd469487.aspx)声明的协变类型参数,在接口中,但为了这个问题的目的,足够好。 – spender

+0

@spender关键字值得一提。谢谢 – Tommy

+0

对不起,我没有清楚地描述这个问题。任务只是一个例子。我伤口实际上在这里得到任务或任务。我编辑了这个问题。 – guogangj