ygetarts
ygetarts

Reputation: 944

Is this a correct use of async void? Xamarin

I'm testing the waters of Xamarin and trying to convert an android project I have to it. I have a very basic login using facebook. My code looks like this:

  public class MainActivity : Activity, IFacebookCallback
  {
    private LoginButton loginButton;
    ICallbackManager callbackManager;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.Main);

        loginButton = FindViewById<LoginButton>(Resource.Id.login_button);
        loginButton.SetReadPermissions(new List<string>() {"email"});

        this.callbackManager = CallbackManagerFactory.Create();
        loginButton.RegisterCallback(callbackManager, this);
    }        

    public async void OnSuccess(Java.Lang.Object result)
    {
        var loginResult = result as LoginResult;
        var accesstoken = loginResult.AccessToken;

        var client = new FacebookApiClient();

        var textview = FindViewById<TextView>(Resource.Id.emailDisplay);            

        try
        {           
            var fbResponse = await GetFaceBookResponse(accesstoken);
            textview.Text = fbResponse.Email;
        }
        catch(System.Exception ex)
        {
            var myException = ex;
        }                  
    }

    private async Task<FacebookResponse> GetFaceBookResponse(AccessToken accessToken)
    {
        var client = new FacebookApiClient();
        var response = await client.GetEmail(accessToken);
        return response;
    }
}

So I'm implementing the OnSuccess method in IFacebookCallback, which requires a void method. This appears to be the only way to do this, which seems ok to me and also appears to be working fine. However, I know it's a no-no to use async with a void return type, except in special situations (event handlers). Just double checking here to make sure this won't cause any problems?

Also, if there is a better way to do this, what is it? While I was googling I found a way using Task.Run:

        var cts = new CancellationTokenSource();
        var ct = cts.Token;
        try
        {
           var fbResponse = await Task.Run(async () =>
            {
                var response = await client.GetEmail(accesstoken);
                return response;
            }, ct);                

            textview.Text = fbResponse.Email;
        }

But I'm not really sure why that would be better than what I'm doing, or if it's actually really any different.

Upvotes: 2

Views: 295

Answers (1)

BoltClock
BoltClock

Reputation: 723648

So I'm implementing the OnSuccess method in IFacebookCallback, which requires a void method. This appears to be the only way to do this, which seems ok to me and also appears to be working fine. However, I know it's a no-no to use async with a void return type, except in special situations (event handlers). Just double checking here to make sure this won't cause any problems?

That's exactly what you're using it for, so it's fine. As long as you're not trying to await that method anywhere in your own code (since async void methods can't be awaited, which is the reason why they're a no-no), you're good.

One of Microsoft's samples also contains a simple async implementation of IFacebookCallback.OnSuccess(), here.

Upvotes: 3

Related Questions