Underscore
Underscore

Reputation: 1057

Implication of calling result on awaited task

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

Answers (1)

Servy
Servy

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

Related Questions