C# Task FromResult vs TaskCompletionSource SetResult

C# Task FromResult vs TaskCompletionSource SetResult,c#,asp.net-web-api,task-parallel-library,async-await,taskcompletionsource,C#,Asp.net Web Api,Task Parallel Library,Async Await,Taskcompletionsource,关于的功能和意义有什么区别 TaskCompletionSource+SetResultvsTask+FromResult 在SendAsync方法中 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (request.RequestUri.Scheme != Uri.UriSc

关于的功能和意义有什么区别

TaskCompletionSource+SetResultvsTask+FromResult

在SendAsync方法中

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    if (request.RequestUri.Scheme != Uri.UriSchemeHttps)
    {
        var response = new HttpResponseMessage(HttpStatusCode.Forbidden) {ReasonPhrase = "HTTPS Required"};
        var taskCompletionSource = new TaskCompletionSource<HttpResponseMessage>();
        taskCompletionSource.SetResult(response);
        return taskCompletionSource.Task;
    }
    return base.SendAsync(request, cancellationToken);
}

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    if (!request.RequestUri.Scheme.Equals(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
    {
        HttpResponseMessage reply = request.CreateErrorResponse(HttpStatusCode.BadRequest, "HTTPS is required for security reason.");
        return Task.FromResult(reply);
    }

    return base.SendAsync(request, cancellationToken);
}
受保护的覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
if(request.RequestUri.Scheme!=Uri.UriSchemeHttps)
{
var response=newhttpresponsemessage(HttpStatusCode.probled){ReasonPhrase=“HTTPS Required”};
var taskCompletionSource=新的taskCompletionSource();
taskCompletionSource.SetResult(响应);
返回taskCompletionSource.Task;
}
返回base.sendaync(请求、取消令牌);
}
受保护的覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
如果(!request.RequestUri.Scheme.Equals(Uri.UriSchemeHttps,StringComparison.OrdinalIgnoreCase))
{
HttpResponseMessage reply=request.CreateErrorResponse(HttpStatusCode.BadRequest,“出于安全原因需要HTTPS”);
返回任务.FromResult(回复);
}
返回base.sendaync(请求、取消令牌);
}

如果您只想返回一个带结果的已完成的
任务
(或没有结果的已完成的
任务
),只需使用
Task.FromResult

Task.FromResult
是一个简单的工具,用于创建具有结果的已完成任务
TaskCompletionSource
是一个更强大的工具,支持一切。您可以设置异常、返回未完成的任务以及稍后设置其结果等等


附言:你似乎试图通过返回一个已完成的任务来“伪造”异步方法。尽管这是最好的方法,但请确保“假装”异步是您真正想要完成的。

我相当肯定
Task.FromResult()
在封面下做了类似的事情


TaskCompletionSource
的一个更好的用例场景是当您自己实现多线程时。在这种情况下,您会立即返回一个等待的任务,直到后台线程完成并调用
TaskCompletionSource.SetResult()
TaskCompletionSource.SetException()

我相信
task.FromResult()
更有效,但您也可以执行以下操作:,国际海事组织,哪个更容易阅读:

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    if (request.RequestUri.Scheme != Uri.UriSchemeHttps)
        return new HttpResponseMessage(HttpStatusCode.Forbidden) {ReasonPhrase = "HTTPS Required"};
    return await base.SendAsync(request, cancellationToken);
}
protectedoverride async Task sendaync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
if(request.RequestUri.Scheme!=Uri.UriSchemeHttps)
返回新的HttpResponseMessage(HttpStatusCode.Forbidden){reasonPhase=“HTTPS Required”};
返回wait base.sendaync(请求、取消令牌);
}

您仍然可以覆盖基的虚拟
SendAsync
,因为
async
不会更改方法签名。

Task.FromResult是.NET 4.5中的一个新添加。它是一个帮助器方法,用于创建TaskCompletionSource并调用SetResult。如果使用.NET 4或更早版本,则必须使用SetResult。

是为同步方法创建任务的方便方法。尽管任务表示异步操作,但并非所有任务都是异步的,可能只是同步方法的简单包装

如果您使用Task.FromResult,那么请在您的文档中说明您的方法不是一个“真正的”异步方法,而是一个语法立方体。这将通知调用者不要期望来自它的异步行为

另一方面,如果要手动创建异步函数,请使用TaskCompletionSource的或方法,如下所述

无论.NET framework的版本如何,始终使用TaskCompletionSource而不是Task.FromResult来创建真正的异步函数

资料来源:


  • 您提到的“.Net 4.5中的新添加项”使它成为我的解决方案,但没有人提到。
    Task.FromResult
    不使用
    TaskCompletionSource
    <代码>任务。FromResult调用特殊的内部构造函数来创建已完成的任务@法比奥:谢谢你的澄清。我可能看到MS的一些垫片代码伪造了向后兼容的方法,并假设它就是这样工作的。@Miller请更新您的答案,包括Fabio的澄清。