【问题标题】:Xamarin: Refactoring to use async/awaitXamarin:重构以使用 async/await
【发布时间】:2014-03-06 12:20:01
【问题描述】:

重构此代码以使用 async/await 的最佳方法是什么?这段代码sn-p来自Xamarin Field Services Sample App

ViewModel 的数据提供者接口

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

登录接口实现。这里只是为了假网络电话睡觉......

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);
        }
}

按钮点击处理程序

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

重构此代码以使用 async/await 的最佳方法是什么?

【问题讨论】:

    标签: c# ios asynchronous xamarin.ios xamarin


    【解决方案1】:

    你可以这样做:

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

    您不需要切换线程,因为 await 捕获当前的 SynchroniztionContext 并将方法的其余部分作为同一上下文的延续发布。对于 UI 线程,这实质上意味着 go to different view 部分也将在 UI 线程上执行。

    您可能还应该检查LoginAsync 操作的结果

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

    我不会进一步重构它,因为它很简单。

    【讨论】:

    • 否则会很好,但部分方法将成为问题,因为该方法需要标记为异步。
    • 感谢您的快速回复!有机会重构 LoginService 实现吗?
    • 我不会担心进一步重构它。通常你提供一个没有CancellationToken 的实现,但你已经通过deafult 值有效地实现了。
    【解决方案2】:

    很难将延迟重构为任何有意义的东西,但它只是这样:

    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;
        }
    }
    

    延迟将替换为 f.e.对服务器进行异步网络调用以确认登录。

    【讨论】:

    • 是的,你在我编辑的时候打败了我。任何可以等待的事情都可以解决问题,您无需开始任务。
    猜你喜欢
    • 1970-01-01
    • 2021-05-08
    • 2020-10-11
    • 2020-08-01
    • 2020-06-22
    • 2021-10-02
    • 1970-01-01
    • 2016-07-26
    • 2016-07-21
    相关资源
    最近更新 更多