19

Could someone please help me modify the code below:

client.ExecuteAsync(request, response => {
    Console.WriteLine(response.Content);
});

Basically I want to use ExecuteAsync method above but don't want to print but return response.Content to the caller.

Is there any easy way to achieve this?

I tried this but doesnt' work:

public T Execute<T>(RestRequest request) where T : new()
{
    var client = new RestClient();
    client.BaseUrl = BaseUrl;
    client.Authenticator = new HttpBasicAuthenticator(_accountSid, _secretKey);
    request.AddParameter("AccountSid", _accountSid, ParameterType.UrlSegment); // used on every request
    var response = client.ExecuteAsync(request, response => {
        return response.data);
    });
}

The above code is from https://github.com/restsharp/RestSharp

Julian
  • 5,290
  • 1
  • 17
  • 40
Nil Pun
  • 17,035
  • 39
  • 172
  • 294

4 Answers4

38

There's the thing... you can't return an asynchronously delivered value, because your calling method will already have returned. Blocking the caller until you have a result defeats the point of using ExecuteAsync. In this case, I'd return a Task<string> (assuming response.Content is a string):

Task<string> GetResponseContentAsync(...)
{
  var tcs=new TaskCompletionSource<string>();
  client.ExecuteAsync(request, response => {
    tcs.SetResult(response.Content);
  });
  return tcs.Task;
}

Now, when the task completes, you have a value. As we move to c#5 async/await, you should get used to stating asynchrony in terms of Task<T> as it's pretty core.

http://msdn.microsoft.com/en-us/library/dd537609.aspx

http://msdn.microsoft.com/en-us/library/hh191443.aspx

spender
  • 117,338
  • 33
  • 229
  • 351
5

With the help of @spender, this is what i got:

You can add new file in RestSharp project, and add this code:

public partial class RestClient
{
    public Task<IRestResponse<T>> ExecuteAsync<T>(IRestRequest request)
    {
        var tcs=new TaskCompletionSource<IRestResponse<T>>();

        this.ExecuteAsync(request, response => 
            {
                tcs.SetResult(
                    Deserialize<T>(request, response)
                );
            });

    return tcs.Task;
    }       
}

This will practically return the full response, with status code and everything, so you can check if the status of the response is OK before getting the content, and you can get the content with:

response.Content
Boris
  • 389
  • 4
  • 12
1

From reading the code it looks like you want to use ExecuteAsGet or ExecuteAsPost instead of the async implementation.

Or maybe just Execute- not sure exactly what type Client is.

Chris Shain
  • 50,833
  • 6
  • 93
  • 125
  • This question is specific to RESTSharp, don't think ExecuteGet is available. – Nil Pun Sep 02 '12 at 08:14
  • According to the code that you linked to, it is defined here (ExecuteAsGet, ExecuteAsPost, and just plain old Execute): https://github.com/restsharp/RestSharp/blob/master/RestSharp/RestClient.Sync.cs – Chris Shain Sep 02 '12 at 16:22
  • It depends on the platform. RestSharp for Windows Phone only contains the async methods – Greg Woods Jul 11 '13 at 13:55
1

At some point, there was a bunch of overloads introduced that support System.Threading.Tasks.Task and had the word "Task" in them. They can be awaited (like HttpClient's methods).

For instance:

  • ExecuteTaskAsync(request) (returns Task<IRestResponse>)
  • ExecuteGetTaskAsync(request) (returns Task<IRestResponse>)
  • ExecuteGetTaskAsync<T>(request) (returns Task<IRestResponse<T>>)

Those then became deprecated in later v106 versions in favour of Task-support being the default I believe, e.g. the first one became client.ExecuteAsync(request).

So these days you can just do:

var response = await client.ExecuteAsync(request);
return response.Content;
benmccallum
  • 1,241
  • 12
  • 27