假设我们有某种基本的异步 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"};
}
}
我们有某种依赖注入(inject)容器:
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
实际以异步方式执行?假设处理程序执行实际的异步工作,该方法是否会正确异步?
(注意:这些是为了提出问题而简化的实现)
最佳答案
如果您等待
任务,那么该方法的其余部分将作为该任务
的延续执行,并且控制权将返回给当前方法的调用者,所以是的,它将是异步的。
这就是 await
的意义所在;异步运行。
在已完成的Task
上调用Result
不是问题。它会阻塞当前线程,直到任务
完成,但正如您所知,它已经完成,这不是问题。
关于c# - 调用结果对等待任务的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30176781/