在等待任务中调用结果的含义

时间:2015-05-11 20:11:31

标签: c# .net asynchronous async-await

鉴于我们有如下所述的某种基本的异步CQRS设置:

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"};
    }
}

我们有一些依赖注入容器:

public class Container
{
    public object Resolve(Type serviceType)
    {
        var possibleTypes = new Dictionary<Type, object>();
        possibleTypes.Add(typeof(GetThings), new GetThingsHandler());
        return possibleTypes[serviceType];
    }
}

对于我们的'RequestBus'实现,由于位于REST样式服务的另一端,所有泛型类型参数信息都将丢失:

    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);
    }

唯一知道的是所有任务都可以返回一个对象,并且我们可以推断出请求的类型和请求返回类型(为简单起见,这里将其视为已知)。

问题是: 在要求await实际以异步方式执行之前,在(void)Task上调用Task.Result?假设处理程序执行实际的异步工作,这个方法是否正确异步?

(注意:这些是为了提问而简化的实现)

1 个答案:

答案 0 :(得分:2)

如果你await任务,那么方法的其余部分将作为Task的延续执行,并且控制权返回给当前方法的调用者,所以是的,它将是异步的

毕竟这是await的重点;表现异步。

在已完成的Result上调用Task不是问题。 阻止当前线程,直到Task完成,但如您所知,它已经完成,这不是问题。