Reputation: 11006
I have a synchronous, generic method that looks like this
public TResponse Execute<TResponse>(Request request) where TResponse : Response
{
return (TResponse) proxy.ExecuteRequest(request);
the proxy is a WCF service reference
It just has one method that takes a request and returns a response. But it is used by passing derived requests and returning derived responses. As you can see above the wrapper method is casting the response to the derived type specified by the generic parameter (TResponse).
You call the method with derived requests and responses
e.g.
Execute<GetSomeDataResponse>(new GetSomeDataRequest());
I am now generating an async service reference so can make use of Tasks
So I would like a method that looks like this
public Task<TResponse> ExecuteAsync<TResponse>(Request request) where TResponse : Response
{
// need to cast to a Task<TResponse>
return proxy.ExecuteRequestAsync(request
that can be called like this
Task<GetSomeDataResponse> res = ExecuteAsync<GetSomeDataResponse>(new GetSomeDataRequest());
So I need a way to cast the Task<Response>
to a Task<TResponse>
I've been reading this which seems kind of the opposite of what I need, but cant quite figure out how to bend it to my use case
How to convert a Task<TDerived> to a Task<TBase>?
any ideas?
Upvotes: 7
Views: 1519
Reputation: 101473
Easy way is use async\await pattern:
public static async Task<TResponse> ExecuteAsync<TResponse>(Request request) where TResponse : Response {
var response = await proxy.ExecuteRequestAsync(request);
return (TResponse) response;
}
A bit more complicated (taken from your linked question) is to use 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;
}
Upvotes: 3