Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ServiceStack "new" api and async await

ServiceStack version 3

I'm quite familiar with https://github.com/ServiceStack/ServiceStack/wiki/New-API and on this page it specifically says "All these APIs have async equivalents which you can use instead, when you need to."

Is it possible to use async await with ServiceStack's new api?

What would the server and client code look like with async await?

[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());

Would some please convert these synchronous examples to asynchronous?

like image 508
Chris Marisic Avatar asked Oct 08 '13 15:10

Chris Marisic


2 Answers

The "async" methods mentioned in the documentation do not return Task so they can't be used with async/await as they are. They actually require callbacks to call on success or failure.

E.g. the signature for GetAsync is :

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

This is the APM-style of asynchronous functions and can be converted to Task-based functions using a TaskCompletionSource, eg:

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

You can call the extension method like this:

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

Unfortunatelly, I had to name the method GetTask for obvious reasons, even though the convention is to append Async to methods that return Task.

like image 102
Panagiotis Kanavos Avatar answered Oct 16 '22 04:10

Panagiotis Kanavos


With ServiceStack 4, GetAsync now returns a Task, so can can simply use await as expected:

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

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

Note: From what I can tell ServiceStack v4 has many breaking changes from v3.x, and has moved away from BSD licensing with usage limits for their free tier: https://servicestack.net/pricing, so upgrading to 4 may not be an option.

like image 22
Chris Curtis Avatar answered Oct 16 '22 05:10

Chris Curtis