这是我非常简单的类,演示了该问题:
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>
,为什么只有在第二种情况下才得到预期的行为?
答案 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
。