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?
Async void methods can wreak havoc if the caller isn't expecting them to be async. When the return type is Task, the caller knows it's dealing with a future operation; when the return type is void, the caller might assume the method is complete by the time it returns.
Async methods can have the following return types: Task, for an async method that performs an operation but returns no value. Task<TResult>, for an async method that returns a value. void , for an event handler.
The recommended return type of an asynchronous method in C# is Task. You should return Task<T> if you would like to write an asynchronous method that returns a value. If you would like to write an event handler, you can return void instead. Until C# 7.0 an asynchronous method could return Task, Task<T>, or void.
Asynchronous tasks run in the background and evaluate functions asynchronously when there is an event. Asynchronous tasks may run only until some work is completed, or they may be designed to run indefinitely. This tutorial describes how to interact with asynchronous tasks.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With