简体   繁体   中英

Xamarin: Refactoring to use async/await

What's the best way to refactor this code to use async/await? This code snippet is from the Xamarin Field Services Sample App

Data provider interface for ViewModels

public interface ILoginService {
            Task<bool> LoginAsync (string username, string password, CancellationToken cancellationToken = default(CancellationToken));
    }

Interface implementation for login. Here just sleeping to fake network call...

public class LoginService : ILoginService {    
   public Task<bool> LoginAsync (string username, string password, CancellationToken cancellationToken = default(CancellationToken)) {
            return Task.Factory.StartNew (() => {
                Thread.Sleep (1000);
                return true;
            }, cancellationToken);
        }
}

Button click handler

partial void Login () {
        //some ui related code
        loginViewModel
            .LoginAsync ()
            .ContinueWith (_ => 
                BeginInvokeOnMainThread (() => {
                    //go to different view
                }));
    }

What's the best way to refactor this code to use async/await?

You can just do this:

partial async void Login () 
{
    //some ui related code
    await loginViewModel.LoginAsync ();
     //go to different view
}

You don't need to switch threads as await captures the current SynchroniztionContext and post the remainder of the method as a continuation on that same context. For UI thread, this essentially means that the go to different view section will be executing on the UI thrad as well.

You probably should check the result of the LoginAsync operation as well

private async void Login () 
{
    //some ui related code
    if(await loginViewModel.LoginAsync())
    {
        //go to different view
    }
    else
    {
       // login failed
    }
}

I wouldn't refactor this any further as it is quite simple.

Hard to refactor delay into anything meaningful but it would simply be like this:

public class LoginService : ILoginService 
{    
    public async Task<bool> LoginAsync (string username, string password, CancellationToken cancellationToken = default(CancellationToken)) 
    {
        await Task.Delay(TimeSpan.FromMilliseconds(1000), cancellationToken);
        return true;
    }
}

The delay would be replaced with fe async web call to the server to confirm login.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM