Perché dovrei creare operazioni WebAPI asincrone anziché sincronizzare?

2022-06-01 16:30:18

Ho la seguente operazione in un'API Web che ho creato:

// GET api/<controller>
[HttpGet]
[Route("pharmacies/{pharmacyId}/page/{page}/{filter?}")]
public CartTotalsDTO GetProductsWithHistory(Guid pharmacyId, int page, string filter = null ,[FromUri] bool refresh = false)
{
    return delegateHelper.GetProductsWithHistory(CustomerContext.Current.GetContactById(pharmacyId), refresh);
}

La chiamata a questo servizio web viene eseguita tramite una chiamata Jquery Ajax in questo modo:

$.ajax({
      url: "/api/products/pharmacies/<%# Farmacia.PrimaryKeyId.Value.ToString() %>/page/" + vm.currentPage() + "/" + filter,
      type: "GET",
      dataType: "json",
      success: function (result) {
          vm.items([]);
          var data = result.Products;
          vm.totalUnits(result.TotalUnits);
      }          
  });

Ho visto alcuni sviluppatori che implementano l'operazione precedente in questo modo:

// GET api/<controller>
[HttpGet]
[Route("pharmacies/{pharmacyId}/page/{page}/{filter?}")]
public async Task<CartTotalsDTO> GetProductsWithHistory(Guid pharmacyId, int page, string filter = null ,[FromUri] bool refresh = false)
{
    return await Task.Factory.StartNew(() => delegateHelper.GetProductsWithHistory(CustomerContext.Current.GetContactById(pharmacyId), refresh));
}

Devo dire, però, che GetProductsWithHistory() è un'operazione piuttosto lunga. Dati il ​​mio problema e il mio contesto, in che modo rendere asincrona l'operazione webAPI mi gioverà?

- David Jiménez Martínez

Source
Risposta


112
  • Nel tuo esempio specifico l'operazione non è affatto asincrona, quindi quello che stai facendo è asincrono su sincronizzazione. Stai solo rilasciando un thread e bloccandone un altro. Non c'è motivo per questo, perché tutti i thread sono thread del pool di thread (a differenza di un'applicazione GUI).

    Nella mia discussione su "async over sync", ho suggerito vivamente che se hai un'API che è implementata internamente in modo sincrono, non dovresti esporre una controparte asincrona che racchiude semplicemente il metodo sincrono in }^{.

    Da Devo esporre i wrapper asincroni per i metodi sincroni?

    Tuttavia, quando si effettuano chiamate WebAPI Task.Run dove c'è un'operazione asincrona effettiva (di solito I/O) invece di bloccare un thread che si trova e attende un risultato, il thread torna al pool di thread e quindi in grado di eseguire qualche altra operazione. Ciò significa soprattutto che la tua applicazione può fare di più con meno risorse e che migliora la scalabilità.