parallel method library example await async c# asp.net-web-api task-parallel-library async-await taskcompletionsource

method - task c# example



Task FromResult vs TaskCompletionSource SetResult (5)

Creo que Task.FromResult() es más eficiente, pero también podría hacer lo siguiente, que es más legible, IMO:

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); }

Aún puede anular el SendAsync virtual de la base, porque async no cambia la firma del método.

¿Cuál es la diferencia con respecto a la funcionalidad y significado de la

TaskCompletionSource + SetResult vs Task + FromResult

en el método 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); }


Estoy bastante seguro de que Task.FromResult() hace algo muy similar debajo de la portada.

Un mejor escenario de caso de uso para TaskCompletionSource es cuando usted mismo implementó multihilo. En ese escenario, devuelve inmediatamente una tarea que se puede esperar, cuyo resultado no se establece hasta que finaliza el hilo de fondo y llama a TaskCompletionSource.SetResult() o TaskCompletionSource.SetException() .


Si todo lo que desea es devolver una Task<TResult> completada Task<TResult> con un resultado (o una Task completada sin una), simplemente use Task.FromResult .

Task.FromResult es una herramienta simple para crear una tarea terminada con un resultado. TaskCompletionSource es una herramienta mucho más robusta que soporta todo. Puede establecer excepciones, devolver una tarea no completada y establecer su resultado más adelante y así sucesivamente

PD: Parece que estás intentando "falsificar" métodos asíncronos devolviendo una tarea terminada. Aunque esa es la mejor manera de hacerlo, asegúrese de que "falsificar" async es realmente lo que quiere lograr.


Task.FromResult fue una nueva adición en .NET 4.5. Es un método auxiliar que crea un TaskCompletionSource y llama a SetResult. Si está utilizando .NET 4 o anterior, tendrá que usar SetResult.


Task.FromResult es un método conveniente para crear una tarea para un método síncrono. Aunque una Tarea representa una operación asíncrona, no todas las Tareas son en realidad asíncronas y pueden ser simples envoltorios para métodos síncronos.

Si utiliza Task.FromResult, incluya en su documentación que su método no es un método asíncrono "real" sino un cubo sintáctico de azúcar. Esto informará al llamante para que no espere un comportamiento asíncrono.

Por otro lado, si desea crear manualmente una función asíncrona, use los métodos SetResult o TrySetResult de TaskCompletionSource como se describe here .

Independientemente de la versión de su marco .NET, siempre use TaskCompletionSource en lugar de Task.FromResult para crear funciones asíncronas reales.

Fuentes:

  1. Task.FromResult
  2. Constructor interno de tareas
  3. TaskCompletionSource.SetResult
  4. TaskCompletionSource.TrySetResult