Xamarin -在非主线程上加载数据



加载页面时,我运行一些从SQLite DB加载项目的代码。因此(我相信是这样)页面加载动画不流畅。所以我决定在App.OnStart中提前加载数据。

Task.Run(itemsStore.LoadItemsAsync);

问题是它总是在主线程中运行。我试着在LoadItemsAsync:

中做一个这样的技巧
while (MainThread.IsMainThread)
{
Debug.WriteLine($"ItemsStore.DoLoadItemsAsync: (2) Is main thread: {MainThread.IsMainThread}");
await Task.Delay(100);
}

但是随后应用程序挂起。

所以我的问题是:如何在后台加载数据,为什么上面的技巧不起作用?我也试过用Task.Yield

我已经改变了应用程序的OnStart方法从:

protected override void OnStart()
{
var itemStore = DependencyService.Get<IItemStore>();
itemsStore.Init(); // !!! HERE THE CHANGE !!!
Task.Run(itemsStore.LoadItemsAsync);
}

protected override void OnStart()
{
var itemStore = DependencyService.Get<IItemStore>();
Task.Run(() => itemsStore.Init());  // !!! HERE THE CHANGE !!!
Task.Run(itemsStore.LoadItemsAsync);
}

现在它不再只在主线程上运行了。有人能给我解释一下吗?

我写了一个小例子供你参考。

以下是xaml代码:
<StackLayout>
<CollectionView x:Name="mytest">
<CollectionView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding .}"></Label>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>

下面是cs代码:

public partial class MainPage : ContentPage
{
ObservableCollection<string> ts = new ObservableCollection<string>();
public MainPage()
{
InitializeComponent();
mytest.ItemsSource = ts;
}
protected override void OnAppearing()
{
base.OnAppearing();
var result = Task.Run(() => myTest());
}
private void myTest()
{
Thread.Sleep(10000);//Time spent in simulated query
ts.Add("aaa");
ts.Add("bbb");
ts.Add("ccc");
}
}

但是根据你的陈述,我不确定你的数据库有多少数据,为了快速查询。使用在数据库中是提高查询效率的最好方法。