2013-10-08 10 views
5

versione ServiceStack 3ServiceStack "nuova" api e asincrone attendono

Sono abbastanza familiarità con https://github.com/ServiceStack/ServiceStack/wiki/New-API e in questa pagina si dice espressamente: "Tutte queste API hanno equivalenti asincrone che è possibile utilizzare, invece, quando è necessario a."

È possibile utilizzare l'attesa asincrona con la nuova API di ServiceStack?

Che aspetto avrebbero il codice server e client con async?

[Route("/reqstars")] 
public class AllReqstars : IReturn<List<Reqstar>> { } 

public class ReqstarsService : Service 
{ 
    public List<Reqstar> Any(AllReqstars request) 
    { 
     return Db.Select<Reqstar>(); 
    } 
} 

client

var client = new JsonServiceClient(BaseUri); 
List<Reqstar> response = client.Get(new AllReqstars()); 

Sarebbe un po 'si prega di convertire questi esempi sincrone a asincrone?

risposta

11

I metodi "asincroni" menzionati nella documentazione non restituiscono l'attività in modo che non possano essere utilizzati con async/await così come sono. In realtà richiedono callback per chiamare in caso di successo o fallimento.

E.g. la firma per GetAsync è:

public virtual void GetAsync<TResponse>(string relativeOrAbsoluteUrl, 
    Action<TResponse> onSuccess, 
    Action<TResponse, Exception> onError) 

Questo è lo stile di APM di funzioni asincrone e può essere convertito a funzioni Task-based utilizzando un TaskCompletionSource, ad esempio:

public static Task<TResponse> GetTask<TResponse>(this JsonServiceClient client, string url) 
    { 
     var tcs = new TaskCompletionSource<TResponse>(); 

     client.GetAsync<TResponse>(url, 
      response=>tcs.SetResult(response), 
      (response,exc)=>tcs.SetException(exc) 
      ); 

     return tcs.Task; 
    } 

è possibile chiamare il metodo di estensione in questo modo:

var result = await client.GetTask<SomeClass>("someurl"); 

Purtroppo, ho dovuto dare un nome al metodo di getTask per ovvie ragioni, anche se la convenzione è di aggiungere Async ai metodi che restituiscono Task.

+0

In realtà, non potevi chiamare il metodo GetAsync? Le firme sarebbero diverse e dovrebbero risolversi bene. Ma grazie per averlo chiarito, non mi è stato completamente chiaro in quei documenti. Cercherò di aggirarli aggiornandoli con le informazioni di questa risposta! –

+1

L'APM è un pattern molto specifico (con i metodi 'Begin' e' End', 'IAsyncResult', ecc.) E il metodo' GetAsync() 'non lo soddisfa. È simile (basato sulla callback), ma non è lo stesso. – svick

+0

@svick meh, se uso il metodo di estensione userò GetAsync(). Immagino che se volessi una chiara denotazione è diverso, anche se leggermente, si adatterebbe GetAsynchronous()/GetAwaitable(). –

6

Con ServiceStack 4, GetAsync ora restituisce un Task, quindi può può semplicemente utilizzare attendono come previsto:

var client = new JsonServiceClient(BaseUri); 
var response = await client.GetAsync(new AllReqstars()); 

documentazione qui: https://github.com/ServiceStack/ServiceStack/wiki/C%23-client#using-the-new-api

Nota: Da quello che posso dire ServiceStack v4 ha molte modifiche da v3.x e si è allontanato dalla licenza BSD con i limiti di utilizzo per il proprio livello gratuito: https://servicestack.net/pricing, quindi l'aggiornamento a 4 potrebbe non essere un'opzione.

+0

FWIW ho chiarito in modo specifico che questa domanda riguarda solo ServiceStack3, non vedo nulla di sbagliato nel lasciare questa risposta qui per completezza. –

+1

Yea non sapeva se sarebbe stato utile o meno, dato che non hai specificato una versione in origine. Ma pensavo che sarebbe stato comunque utile ad altri spettatori di questa domanda.Grazie per l'aggiornamento –