2016-07-06 48 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