5

Ho visto alcune informazioni contrastanti sull'argomento e vorrei ottenere una certa chiarezza qui.Come implementare correttamente l'asincronia in web api 2

In origine, si dovrà azioni Api Web come:

  • Model Action();
  • HttpResponseMessage Action();

Poi, con l'aggiunta di miglioramenti TPL per Api Web, si potrebbe avere

  • Task<Model> Action();
  • Task<HttpResponseMessage> Action();

E presumibilmente, ASP.NET sarebbe abbastanza intelligente per gestire quelle di attesa per il compito di finire, e rilasciando il filo che raccolse la richiesta nel frattempo.

Bellissima! Tutto era semplice al mondo. Ma ora, con Web API 2, c'è l'aggiunta di IHttpActionResult, un terzo caso, che fornisce il metodo Task<HttpResponseMessage> ExecuteAsync().

Prima di tutto, se si controlla implementazioni di IHttpActionResult, si vede che ogni ExecuteAsync in realtà restituisce solo Task.FromResult (non ASYNC a tutti, e non sembra come sarebbe dare alcun guadagno di prestazioni sopra sincrono ritorno HttpResponseMessage). Secondo, vedo le persone che consigliano di usare Task<IHttpActionResult>, che sembra completamente ridondante. Vedo persino una manciata di persone che suggeriscono di unire questi approcci e di restituire Task.Factory.StartNew(..) alla tua azione, il che sembra un po 'assurdo.

Quindi qual è il modo corretto di utilizzare IHttpActionResult in modo asincrono? Implementa semplicemente la tua e esegui operazioni asincrone? O restituisci Task<IHttpActionResult>, esegui il tuo metodo async e attendi su operazioni legate all'IO prima di chiamare su return Ok() (o equivalente)?

Per essere chiari, ovviamente comprendo che passare semplicemente da IHttpActionResult Action(); a Task<IHttpActionResult> Action(); senza modificare il metodo non aiuterà in alcun modo. È l'intento dello ExecuteAsync che è un puzzle.

https://stackoverflow.com/a/21609402/661422

+0

usando 'Task.FromResult' è un dettaglio di implementazione - che è , l'implementatore ha preso la decisione di non usare l'asincronicità, ma può decidere di usarlo in futuro, se è giustificato. Considerando che non esiste un buon modo per implementare un'API sincrona in modo asincrono. –

risposta

3

Tutto era semplice nel mondo. Ma ora, con il Web API 2, v'è un 'aggiunta di IHttpActionResult

IHttpActionResult è venuto al mondo con lo scopo di incapsulare la generazione di HttpResponseMessage. Ciò consentirebbe di incapsulare la logica comune per la creazione di risposte simili all'interno di un insieme di classi che potrebbero essere riutilizzate, facilmente testate e che libererebbero le azioni del controller per gestire la reale logica di business.

Prima di tutto, se si ispezionano le implementazioni di IHttpActionResult, si vede che ogni ExecuteAsync in realtà restituisce solo Attività.FromResult

che sto supponendo che avviene perché, per esempio, NotFound(); e Ok() metodi di estensione semplicemente restituiscono un costruito HttpResponseMessage, niente di più. Forse non ti sei imbattuto in scenari del mondo reale in cui sarebbe stato necessario.

In secondo luogo, vedo le persone che consigliano di utilizzare Task, che sembra completamente ridondante.

Si restituisce un Task<IHttpActionResult> se l'azione utilizza un'operazione naturalmente asincrona. Non vedo come possa essere ridondante. È necessario.

Quindi qual è il modo corretto di utilizzare IHttpActionResult in modo asincrono?

Il modo corretto è lo stesso di tutti i metodi asincroni. Diciamo che si desidera effettuare il login ogni risposta prima di tornare a un terzo quadro di registrazione del partito, che espone un'API asincrona tramite HTTP endpoint, faresti:

public class LogActionResult : IHttpActionResult 
{ 
    string uri = /* ... */ 

    public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) 
    { 
     var response = new HttpResponseMessage() 
     { 
      Content = new StringContent(_value), 
      RequestMessage = _request 
     }; 

     var httpClient = new HttpClient(); 
     await httpClient.PostAsJsonAsync(uri, response); 

     return response; 
    } 
} 

Asynchronoysly registrare e restituire il HttpResponseMessage. Se non si dispone di un'operazione asincrona, Task.FromResult andrebbe perfettamente bene.

+0

Quindi, in pratica, le persone vanno avanti e creano implementazioni di IHttpActionResult in scenari del mondo reale? – Kir

+0

@ Kir Sì, lo fanno. –

0

non mi piace il modo in cui ho bisogno di implementare interfacce vendor che hanno cambiato da versione a versione, ci sono la versione più precisi:

public class FibonacciController : ApiController 
{ 
    public IHttpActionResult Get(int fibN) 
    { 
     Task.Factory.StartNew(() => 
     { 
      var fibNResult = FibonacciHelpers.CalculateFibonacci(fibN); 
     }); 

     return Ok(); 
    } 
} 
Problemi correlati