Reputation: 1057
Given we have some kind of rudimentary async CQRS setup like the below:
public interface IRequest<TReturn> { }
public interface IRequestHandler<TRequest, TReturn> where TRequest : IRequest<TReturn>
{
Task<TReturn> RequestAsync<TRequest>(TRequest request);
}
public class GetThings : IRequest<string[]> { }
public class GetThingsHandler : IRequestHandler<GetThings, string[]>
{
public async Task<string[]> RequestAsync<TRequest>(TRequest request)
{
await Task.Run(() => Thread.Sleep(200));
return new[] {"Tim", "Tina", "Tyrion"};
}
}
And we have some kind of dependency injection container:
public class Container
{
public object Resolve(Type serviceType)
{
var possibleTypes = new Dictionary<Type, object>();
possibleTypes.Add(typeof(GetThings), new GetThingsHandler());
return possibleTypes[serviceType];
}
}
For our 'RequestBus' implementation, all generic type parameter information is lost, due to being on the other end of a REST style service:
public async Task<object> GetRequest(object o)
{
Type t = o.GetType();
object handler = container.Resolve(t);
var methodInfo = handler.GetType().GetMethod("RequestAsync");
methodInfo = methodInfo.MakeGenericMethod(typeof (object));
Task methodInvocationTask = (Task)methodInfo.Invoke(handler, new[] {o});
await methodInvocationTask;
// Or: return ((dynamic) methodInvocationTask).Result;
return methodInvocationTask.GetType().GetProperty("Result").GetValue(methodInvocationTask);
}
The only thing that is known is that all tasks may return an object and that we can deduce the type of the request and request return type (it is treated as known here for simplicity).
The question is:
Is calling await
on the (void) Task
before asking for Task.Result
actually executing in an async way? Assuming the handler does actual async work is this method going to be properly async?
(Note: these are simplified implementations for the sake of asking a question)
Upvotes: 2
Views: 253
Reputation: 203821
If you await
the task then the rest of the method is executed as a continuation of that Task
and control is returned to the caller of the current method, so yes, it'll be asynchronous.
That is the point of await
after all; to behave asynchronously.
Calling Result
on an already completed Task
isn't a problem. It will block the current thread until the Task
has completed, but as you know it's already completed, that's not a problem.
Upvotes: 3