返回Task <httpresponsemessage>

时间:2018-12-20 13:45:42

标签: c# asp.net asp.net-web-api2 task-parallel-library

这是我非常简单的类,演示了该问题:

public class SimpleHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            return new Task<HttpResponseMessage>(
                        () => new HttpResponseMessage(HttpStatusCode.Unauthorized));

            //return base.SendAsync(request, cancellationToken);
        }
    }

预期的行为是401响应。如果我对其进行调试,则执行将到达return语句,并在我按F5时继续执行,但是http请求永远不会返回,并且http客户端最终将等待超时。

我真的很困惑,因为我在做编译器告诉我的事情:返回Task<HttpResponseMessage>。对base.SendAsync的调用工作正常。我在这里想念什么?

修改:

好,所以我发现了

return Task.FromResult(new HttpResponseMessage(HttpStatusCode.Unauthorized));

按预期工作。但是,我想了解上述方法为什么会失败?在这两种情况下,我都在创建Task<HttpResponseMessage>,为什么只有在第二种情况下才得到预期的行为?

2 个答案:

答案 0 :(得分:0)

您可以使用静态Task.FromResult方法,该方法用于创建作为特定值包装的Task:

Task.FromResult<HttpResponseMessage>(new HttpResponseMessage(HttpStatusCode.Unauthorized));

答案 1 :(得分:0)

有很大的不同。使用构造函数创建的Task表示尚未运行的Task,因此还没有结果集。在您的情况下,无需执行任何工作,因此无需创建和运行任务。否则为You should use Task.Run instead of a constructor

并且由于您仅在示例中创建了Task,并且未调用Start(),因此它将具有状态Created,并且由于无法启动而永远不会自行完成。因此,您的过程将挂起,因为在管道的更深处,系统将等待任务完成。

使用FromResult创建的第二个任务表示已完成并具有设置值作为结果的任务。

检查两个Task的Status属性,并注意差异。 (创建与RanToCompletion)

由于您没有实际工作要做,应该坚持使用FromResult