2016-05-13 83 views
6

我有一個看起來像這樣鑄造任務<T>的任務<DerivedT>

public TResponse Execute<TResponse>(Request request) where TResponse : Response 
{ 
    return (TResponse) proxy.ExecuteRequest(request); 

代理同步,通用的方法是一個WCF服務引用

它只是一個方法,它接受請求,並返回一個響應。但通過傳遞派生請求和返回派生響應來使用它。正如您在上面看到的那樣,wrapper方法將響應轉換爲通用參數(TResponse)指定的派生類型。

您使用派生請求和響應調用方法

例如,

Execute<GetSomeDataResponse>(new GetSomeDataRequest()); 

我現在產生一個異步服務引用,以便可以利用任務

,所以我想,看起來像這樣

public Task<TResponse> ExecuteAsync<TResponse>(Request request) where TResponse : Response 
{ 
    // need to cast to a Task<TResponse> 
    return proxy.ExecuteRequestAsync(request 

,可以這樣調用

的方法
Task<GetSomeDataResponse> res = ExecuteAsync<GetSomeDataResponse>(new GetSomeDataRequest()); 

所以我需要一種方法來將Task<Response>轉換爲Task<TResponse>

我一直在閱讀這裏面似乎有點什麼,我需要相反的,但不能完全弄清楚如何將它彎曲到我的使用情況

How to convert a Task<TDerived> to a Task<TBase>?

什麼想法?

+0

嗯,你永遠可以'回報(TDerived)(等待ExecuteRequestAsync(request));'。 – Luaan

+0

@Luaan不幸的是,ExecuteRequestAsync不是.net 4.5意義上的異步方法 - 它只是返回任務。它的簽名中沒有async關鍵字(它由svcutil生成,所以我不能改變它) – ChrisCa

+1

@ChrisCa ExecuteRequestAsync不需要任何async關鍵字,因此您的ExecuteAsync可以。 – Evk

回答

2

容易的方法是使用異步\的await模式:

public static async Task<TResponse> ExecuteAsync<TResponse>(Request request) where TResponse : Response { 
    var response = await proxy.ExecuteRequestAsync(request); 
    return (TResponse) response; 
} 

更復雜一些(來自鏈接的問題採取的)是使用TaskCompletionSource

public static Task<TResponse> ExecuteAsync2<TResponse>(Request request) where TResponse : Response { 
    var tcs = new TaskCompletionSource<TResponse>(); 
    proxy.ExecuteRequestAsync(request).ContinueWith(t => { 
     if (t.IsFaulted) 
      tcs.TrySetException(t.Exception.InnerExceptions); 
     else if (t.IsCanceled) 
      tcs.TrySetCanceled(); 
     else 
      tcs.TrySetResult((TResponse) t.Result); 
     }, TaskContinuationOptions.ExecuteSynchronously); 
    return tcs.Task; 
} 
+0

啊 - 當然。不能相信我看不到你的第一個例子 - 謝謝! – ChrisCa