【问题标题】:Implication of calling result on awaited task调用结果对等待任务的影响
【发布时间】: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


【解决方案1】:

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

这毕竟是await 的意义所在;以异步方式运行。

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

【讨论】:

  • 谢谢,根据我对异步的了解,我认为是这种情况,但想验证它是否正确。
猜你喜欢
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2017-06-02
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 2019-02-24
  • 1970-01-01
相关资源
最近更新 更多