如何在后台准备应用程序数据?

时间:2016-07-16 12:54:20

标签: c# .net xamarin xamarin.forms

我正在开发一个Xamarin Forms应用程序,但我认为我的问题不是特定于Xamarin。 在用户输入密码后(当然只有在引脚正确时),我会向他显示标签页。这些页面中的每一个都有一些控件,但更重要的是,每个页面都必须使用异步调用从Web获取一些数据。现在,由于我的应用程序有几个选项卡,我想并行(非连续)获取每个选项卡的所有数据。到目前为止我实施的是:

    public MainTabbedPage(bool requirePin)
    {
        if (requirePin)
        {
            Navigation.PushModalAsync(new PinEntryPage(this));
        }
        InitializeComponent();

    }

    public void InitializeChildren()
    {
        try
        {
            var page1 = new Page1();
            page1.RefreshData();

            var page2 = new Page2();
            page2.RefreshButtons();
            page2.RefreshData();

            var page3 = new Page3();
            page3.RefreshData();

            Children.Add(page1);
            Children.Add(page2);
            Children.Add(page3);
        }
        catch (Exception ex)
        {
            // some error handling...
        }
    }

虽然所有RefreshData()RefreshButtons()都是这样的:

    public void RefreshData()
    {
        Task.Run(
            () =>
            {
                var data = ApiSingleton.Instance.GetData().Result;
                // some data manipulations
                Device.BeginInvokeOnMainThread(() => /* some UI manipulation*/);
                }
            });
    }

现在,虽然这似乎做得对,但我想知道这是否是正确的做法,如果没有,那是什么?

1 个答案:

答案 0 :(得分:1)

这样做:

public MainTabbedPage(bool requirePin)
{
    if (requirePin)
    {
        Navigation.PushModalAsync(new PinEntryPage(this));
    }
    InitializeComponent();
}

public async void InitializeChildren()
{
    try
    {
        var page1 = new Page1();
        await page1.RefreshData();

        var page2 = new Page2();
        await page2.RefreshButtons();
        await page2.RefreshData();

        var page3 = new Page3();
        await page3.RefreshData();

        Children.Add(page1);
        Children.Add(page2);
        Children.Add(page3);
    }
    catch (Exception ex)
    {
        // some error handling...
    }
}

对于方法刷新方法:

public async Task RefreshData()
{
    var data = await ApiSingleton.Instance.GetData();
    // some data manipulations
    // you are on the UI thread here 
    // so there is no nead for BeginInvokeOnMainThread       
}

作为加速操作的替代方法,您可能希望立即启动所有页面的数据引用。如果这是您想要的,请将InitializeChildren更改为以下内容:

public async void InitializeChildren()
{
    try
    {
        var page1 = new Page1();
        var refreshPage1Task = page1.RefreshData();

        var page2 = new Page2();
        var refreshButtonsPage2Task = page2.RefreshButtons();
        var refreshPage2Task = page2.RefreshData();

        var page3 = new Page3();
        var refreshPage3Task = page3.RefreshData();

        await Task.WhenAll( new Task[] {
           refreshPage1Task, refreshPage2Task,
           refreshPage3Task, refreshButtonsPage2Task } );

        Children.Add(page1);
        Children.Add(page2);
        Children.Add(page3);
    }
    catch (Exception ex)
    {
        // some error handling...
    }
}

这将立即开始所有页面的刷新,因此网络操作可以同时运行。每次调用后仍将返回UI线程。 Task.WhenAll将确保仅在完成所有刷新操作后才将页面附加到Children集合。