我有一个看起来像这样的同步通用方法
public TResponse Execute<TResponse>(Request request) where TResponse : Response
{
return (TResponse) proxy.ExecuteRequest(request);
代理是WCF服务引用
它只有一个接收请求并返回响应的方法。但它通过传递派生请求和返回派生响应来使用。如上所示,wrapper方法将响应转换为泛型参数(TResponse)指定的派生类型。
您使用派生的请求和响应调用方法
e.g。
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 :(得分:2)
简单方法是使用async \ await pattern:
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;
}