【发布时间】:2015-05-11 20:11:31
【问题描述】:
鉴于我们有一些基本的异步 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);
}
唯一已知的是所有任务都可能返回一个对象,并且我们可以推断出请求的类型和请求返回类型(为简单起见,此处视为已知)。
问题是:
在请求Task.Result 实际以异步方式执行之前,是否在(void)Task 上调用await?假设处理程序执行实际异步工作,此方法是否会正确异步?
(注意:这些是为了提问而简化的实现)
【问题讨论】:
-
测试起来很简单。计时方法的执行;如果它立即返回,它是异步的,如果它阻塞了很长时间,它不是。
-
最后三行可以替换为
return await (dynamic)methodInfo.Invoke(handler, new[] { o });
标签: c# .net asynchronous async-await