What is the difference concerning the functionality and meaning of the
TaskCompletionSource + SetResult vs Task + FromResult
in the SendAsync method?
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); }
The TaskCompletionSource class is a great way to convert such code into a Task you can simply await . It's a bit of additional work, but the result is much easier to read and use. Be sure to take full advantage of TaskCompletionSource in your asynchronous C# code!
Yes, as long as the object can be used on a different thread than the one it was created on (of course). Is a memory barrier required? Nope.
Gets a task that has already completed successfully.
Task.FromResult was a new addition in .NET 4.5. It is a helper method that creates a TaskCompletionSource and calls SetResult. If you are using .NET 4 or earlier you will have to use SetResult.
If all you want is to return a completed Task<TResult>
with a result (or a completed Task
without one), simply use Task.FromResult
.
Task.FromResult
is a simple tool to create a finished task with a result. TaskCompletionSource
is a much more robust tool that supports everything. You can set exceptions, return a non-completed task and set it's result later and so forth
P.S: It seems like you're trying to "fake" async methods by returning a finished task. Although that's the best way to do it, make sure "faking" async is really what you want to accomplish.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With