3

I have a method that returns a DropboxClient and I need to await a method to be able to get an AccessToken required to create this DropboxClient. The snippet of code where I have the problem is:

OAuth2Response authUriComplete = 
    await Dropbox.Api.DropboxOAuth2Helper.ProcessCodeFlowAsync(token, 
    options.ClientId, options.ClientSecret);

var dbx = new DropboxClient(authUriComplete.AccessToken);
return dbx;

So I can't figure out how to get this method working, I need to create a method that returns me the DropboxClient, I know that I could return the task and then await it outside the method but that isn't what I need.

Wim Ombelets
  • 5,097
  • 3
  • 39
  • 55
eljiwo
  • 687
  • 1
  • 8
  • 29
  • if you are going to write a blocking function that returns a final dropbox client instance, then you will need to obtain the accesstoken synchronously as well – Cee McSharpface Jul 27 '16 at 09:09
  • 1
    Possible duplicate of [Calling async method synchronously](http://stackoverflow.com/questions/22628087/calling-async-method-synchronously) – Anton Sizikov Jul 27 '16 at 09:09

3 Answers3

1

Once you start with async/await, you kind of need to follow that up the chain. So your method should probably look like

public async Task<DropboxClient> GetClient()
{
   OAuth2Response authUriComplete = 
           await Dropbox.Api.DropboxOAuth2Helper.ProcessCodeFlowAsync(token, options.ClientId, options.ClientSecret);

   return new DropboxClient(authUriComplete.AccessToken);
}

And you would call that as:

var dbx = await GetClient();

If you wanted to not use await there you can also do

var dbx = GetClient().Result;
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • thanks, it didn't worked returning a DropboxClient object, didn't know why but i just changed to Task and returned authUriComplete.AccessToken and created the object after the call, i'm calling it with the await. – eljiwo Jul 27 '16 at 10:24
1

I need to create a method that returns me the DropboxClient, I know that I could return the task and then await it outside the method but that isn't what I need.

If you are consuming an asynchronous operation, then your consuming method should also be asynchronous. This is the natural, proper way to use async/await. I call this "async all the way" in my article on async best practices.

There are some scenarios where existing code makes this infeasible, or out-of-date third-party or framework code makes this impossible. In this case, you can use one of the hacks described in my article on brownfield async development.

Please note that there is no hack that works in all scenarios! Every hack has some kind of drawback. In the case of the blocking hack, the drawback is a potential deadlock.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
0

The await keyword will suspend execution of the method until it completes. therefore dbx won't be executed until after authUriComplete has its value, and once it does it will return the dropboxclient.

However, depending on the rest of the code, it may continue execution in the caller before this function returns. If that is the issue, you need to organise your code such that whatever you need done after the dropboxclient is returned awaits this happening.

Why do you think you don't need to await the task? You can get the Dropbox client by setting it up using the Task<DropboxClient> rather than just Task.

See Jamiec's answer for detail.