我正在开发一个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*/);
}
});
}
现在,虽然这似乎做得对,但我想知道这是否是正确的做法,如果没有,那是什么?
答案 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集合。