我选择了ListView
项目时会执行代码。由于此代码可能要花费大量时间才能执行,因此我想在运行时显示ActivityIndicator
。
我已经阅读了很多有关ActivityIndicator
的帖子,并且我相信我已经正确设置了它。我很确定我的问题是由于正在运行的代码阻塞了UI线程,因为UI在此过程中完全冻结了。
我已经尝试过通过使用async / await而没有运气的所有变化,所以我假设我仍然在做错误的事情。
这是我的代码:
private ListItem selectedList;
public ListItem SelectedList
{
get
{
return selectedList;
}
set
{
if (selectedList != value)
{
var oldValue = selectedList;
selectedList = value;
buildThisList();
}
}
}
private async void buildThisList()
{
StatusBarIsVisibile = true;
ThisList = Task.Run(async () =>
{
return await buildBnBList(SelectedList, selectedLocation,
thisYearList.ListId)
.ConfigureAwait(false);
}).Result; // 1.8 seconds
StatusBarIsVisibile = false;
ThisList.MainVM = this;
ThisList.BuildView();
PIShowListHeaderText = SelectedList.Title.Trim();
}
private async Task<BnBList> buildBnBList(ListItem pSelectedList, State pselectedLocation, int pListId)
{
BnBList newList = new BnBList(pSelectedList, pselectedLocation, pListId);
List<BirdsnBflysMaster> bbfList =
App.BnBRepo.GetBirdsnBflys(selectedList.ListType); // 1.3 seconds
Lists parentList = App.BnBRepo.GetAList(SelectedList.ListId); // .5 seconds
BnBItem newBnBItem;
foreach (BirdsnBflysMaster bbf in bbfList) // .4 seconds
{
newBnBItem = new BnBItem(parentList, bbf, selectedLocation, newList, thisYearList.ListId);
newList.ListAll.Add(newBnBItem);
if (newBnBItem.ListTypeID == "Bird")
{
...
}
else
{
...
}
}
return newList;
}
所以:
buildThisList
属性更改时,会调用SelectedList
。buildThisList
调用buildBnBList
这是耗时的过程。buildBnBList
中没有异步完成的任何内容。StatusBarIsVisible
绑定到IsVisible
的IsRunning
和ActivityIndicator
。我该如何编码,以便执行
buildBnBList
不会阻塞UI线程? 最佳答案
是的,您是带有异步代码的混合阻塞(.Result
),可能会导致死锁。除非在偶数处理程序中,否则应避免使用async void
。
那么,为什么不这样做呢?
创建一个事件和事件处理程序。
public event EventHandler ListSelected = delegate { }
现在,这应该允许您创建事件处理程序
private async void OnListSelected(object sender, EventArgs e) {
StatusBarIsVisibile = true;
ThisList = await buildBnBList(SelectedList, selectedLocation, thisYearList.ListId);
StatusBarIsVisibile = false;
ThisList.MainVM = this;
ThisList.BuildView();
PIShowListHeaderText = SelectedList.Title.Trim();
}
您显然会订阅该活动(当然是在生命周期的早期)
this.ListSelected += OnListSelected;
并根据需要引发活动
private ListItem selectedList;
public ListItem SelectedList {
get {
return selectedList;
}
set {
if (selectedList != value) {
var oldValue = selectedList;
selectedList = value;
OnListSelected(this, EventArgs.Empty);
}
}
}
关于c# - 如何正确使用async/await来显示Xamarin Forms ActivityIndicator,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46064707/