user2169047
user2169047

Reputation: 77

Waiting for ExecuteAsync() result

I have the following problem with my RestSharp implementation. How can I get my application to wait for the response from ExecuteAsync() before continuing?

I tried different solutions:

First (the method doesn't wait for the ExecuteAsync response):

public Task<Connection> Connect(string userId, string password)
    {
        var client = new RestClient(_baseUrl)
            {
                Authenticator = new SimpleAuthenticator("user", userId,
                    "password", password)
            };
        var tcs = new TaskCompletionSource<Connection>();
        var request = new RestRequest(AppResources.Authenticating);
        client.ExecuteAsync<Connection>(request, response =>
            {
                tcs.SetResult(new JsonDeserializer().
                     Deserialize<Connection>(response));
            });
        return tcs.Task;
    }   

So I tried this, but the application freezes :

   public Task<Connection> Connect(string userId, string password)
    {
        EventWaitHandle executedCallBack = new AutoResetEvent(false);
        var client = new RestClient(_baseUrl)
            {
                Authenticator = new SimpleAuthenticator("user", userId, 
                     "password", password)
            };
        var tcs = new TaskCompletionSource<Connection>();
        var request = new RestRequest(AppResources.Authenticating);
        client.ExecuteAsync<Connection>(request, response =>
            {
                tcs.SetResult(new JsonDeserializer().
                          Deserialize<Connection>(response));
                executedCallBack.Set();
                });
        executedCallBack.WaitOne();
        return tcs.Task;
    }   

Upvotes: 2

Views: 10342

Answers (1)

Paul Annetts
Paul Annetts

Reputation: 9604

I think you are missing the point of Task and the async/await pattern.

You don't wait inside this method, but because you are returning a Task<> it allows a caller to wait for it asynchronously it if chooses.

A caller would be something like this:

 public async void ButtonClick(object sender, RoutedEventArgs args)
 {
     Connection result = await restClient.Connect(this.UserId.Text, this.Password.Text);

      //... do something with result
 }

The compiler knows how to make this code, which is very similar to the synchronous (blocking) equivalent, and turn it into asynchronous code.

Notice the async and await keywords, and notice that Task<Connection> has turned in Connection.

Given that: your first code snippet looks OK.

The second one is likely to cause an issue as you're introducing another threading mechanism (namely a semaphore AutoResetEvent). In addition @HaspEmulator is right - if this is on the UI thread this is known to deadlock a WP app.

Upvotes: 4

Related Questions