When working on data APIs which use async rest calls (I am using RestSharp.Portable), what is the best way to handle return values? Since async function can only return a Task or Task ... but the caller has no way to getting back to the return value ... how would the API return data back to the caller? Global properties?
From what I have read so far, it appears that callback functions are the only way to interact with Response Data?
Take the following method for example; previously I was not using async Rest library and was able to return a value but after converting it to use RestSharp.Portable, I dont see a way to return the value:
public async Task<EntityResourceDescriptor> GetEntityDescriptor(string entityType)
{
TaskCompletionSource<EntityResourceDescriptor> tcs = new TaskCompletionSource<EntityResourceDescriptor>();
var req = new RestRequest("/qcbin/rest/domains/{domain}/projects/{project}/customization/entities/{entityType}");
AddDomainAndProject(req);
req.AddParameter("entityType", entityType, ParameterType.UrlSegment);
client.ExecuteAsync<EntityResourceDescriptor>(req, (res) =>
{
if (res.ResponseStatus == ResponseStatus.Error)
{
tcs.TrySetException(res.ErrorException);
}
else
{
tcs.SetResult(res.Data);
}
}
);
return tcs.Task;
}
Here all I can do is return Task but the caller still has no way to get to the response data or am I missing something obvious? Can the caller subscribe to an event which gets fired at Task.Completed etc.?
I am very fuzzy on this async concept. Are there any examples of writing Portable data APIs?
I think you'll really need to take a step back and read about how to use the
async
andawait
keywords. Among other things, you'll need to understand some of the compiler magic that happens behind the scenes when codingasync
methods.Here is a good place to start: Asynchronous Programming with Async and Await.
More to your question, the Return Types and Parameters section has this to say:
It then gives the following code example:
Notice how despite the method return type of
Task<int>
, thereturn
statement simply returns anint
, not aTask<int>
. That's basically because there is some compiler magic going on that makes this legal only inasync
methods.Without wanting to get into all the details, you should also know that the caller of the
async
method is normally expected to do so using theawait
keyword, which knows how to deal with theTask
orTask<TResult>
return values and automatically unwraps the actual expected return value for you in a transparent manner (more compiler magic behind the scenes).So for the above example, here is one way to call it:
Or, if you wish to start the async method, perform some other work in the meantime, and then wait for the async method to complete, this can be done like this:
Hopefully this gives you a general idea of how to pass values back from an async method.
For your specific example, I am not familiar with RestSharp (never used it). But from what little I read, I think you'll want to use
client.ExecuteTaskAsync<T>(request)
instead ofclient.ExecuteAsync<T>(request, callback)
to better fit in theasync-await
model.I'm thinking your method would instead look something like this:
Your calling code would then look like this:
I hope you manage to get this working. But again, make sure to read the documentation about the
async-await
style of programming. It's very neat once you wrap your head around the compiler magic that is done for you. But it's so easy to get lost if you don't take the time to really understand how it works.