我有选择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
的{{1}}和IsRunning
。如何对此进行编码,以便执行ActivityIndicator
不会阻止UI线程?
答案 0 :(得分:4)
是的,您使用异步代码进行混合阻止(.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);
}
}
}