鉴于我们有如下所述的某种基本的异步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
?假设处理程序执行实际的异步工作,这个方法是否正确异步?
(注意:这些是为了提问而简化的实现)
答案 0 :(得分:2)
如果你await
任务,那么方法的其余部分将作为Task
的延续执行,并且控制权返回给当前方法的调用者,所以是的,它将是异步的
毕竟这是await
的重点;表现异步。
在已完成的Result
上调用Task
不是问题。 将阻止当前线程,直到Task
完成,但如您所知,它已经完成,这不是问题。