我有问题。我为我的ViewModel
创建了这个CollectionView
:
public class TemplateListViewModel
{
public double WidthHeight { get; set; }
public ICommand LoadTemplates => new Command(MyHandler);
public int CurrentTemplateCountReceived;
public bool HitBottomOfList = false;
public ObservableCollection<TemplateSource> sourceList { get; set; }
public TemplateListViewModel()
{
CurrentTemplateCountReceived = 0;
sourceList = new ObservableCollection<TemplateSource>();
var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
var width = mainDisplayInfo.Width;
var density = mainDisplayInfo.Density;
var ScaledWidth = width / density;
WidthHeight = (ScaledWidth / 2);
loadingTemplates += onLoadingTemplates;
LoadTemplateList();
}
private event EventHandler loadingTemplates = delegate { };
private Task LoadTemplateList()
{
loadingTemplates(this, EventArgs.Empty);
return null;
}
private async void onLoadingTemplates(object sender, EventArgs args)
{
if (HitBottomOfList == false)
{
List<Template> templateList = await App.RestService.GetTemplates(App.User, CurrentTemplateCountReceived);
if (templateList != null)
{
foreach (var template in templateList)
{
ImageSource source = ImageSource.FromUri(new Uri("mysite.org/myapp/" + template.FileName));
TemplateSource templateSource = new TemplateSource { Id = template.Id, Source = source, WidthHeight = WidthHeight, FileName = template.FileName };
sourceList.Add(templateSource);
}
CurrentTemplateCountReceived = sourceList.Count;
}
else
{
HitBottomOfList = true;
}
}
}
bool handling = false;
public void MyHandler()
{
// already handling an event, ignore the new one
if (handling) return;
handling = true;
LoadTemplateList();
handling = false;
}
}
现在的作用是:它从我的网页收集图像位置,然后为这些收集的图像创建ImageSources
,并将其添加到sourceList。现在,我还在xaml中创建了一个RemainingItemsThresholdReachedCommand="{Binding LoadTemplates}"
,因此当它几乎到达CollectionView
底部时,它会通过调用以下命令来收集更多数据:ICommand LoadTemplates => new Command(MyHandler);
。此事件被触发了很多次,所以我创建了此处理程序:
public void MyHandler()
{
// already handling an event, ignore the new one
if (handling) return;
handling = true;
LoadTemplateList();
handling = false;
}
检查是否已经处理了事件。
问题是,在MyHandler
中,LoadTemplateList()
没有等待结果,这导致对我的网页的许多调用,因为handling
将立即设置为false
!
现在如何等待LoadTemplateList()
?
现在如何等待LoadTemplateList()?
使用await
关键字:
handling = true;
await LoadTemplateList();
handling = false;
但是,它仍然会提前返回,因为代码正在执行一些时髦的私有EventHandler
任务。如果仅删除所有多余的代码并将异步代码移至LoadTemplateList
,它将可以正常工作:
public class TemplateListViewModel
{
public double WidthHeight { get; set; }
public ICommand LoadTemplates => new Command(MyHandler);
public int CurrentTemplateCountReceived;
public bool HitBottomOfList = false;
public ObservableCollection<TemplateSource> sourceList { get; set; }
public TemplateListViewModel()
{
CurrentTemplateCountReceived = 0;
sourceList = new ObservableCollection<TemplateSource>();
var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
var width = mainDisplayInfo.Width;
var density = mainDisplayInfo.Density;
var ScaledWidth = width / density;
WidthHeight = (ScaledWidth / 2);
MyHandler();
}
private async Task LoadTemplateList()
{
if (HitBottomOfList == false)
{
List<Template> templateList = await App.RestService.GetTemplates(App.User, CurrentTemplateCountReceived);
if (templateList != null)
{
foreach (var template in templateList)
{
ImageSource source = ImageSource.FromUri(new Uri("mysite.org/myapp/" + template.FileName));
TemplateSource templateSource = new TemplateSource { Id = template.Id, Source = source, WidthHeight = WidthHeight, FileName = template.FileName };
sourceList.Add(templateSource);
}
CurrentTemplateCountReceived = sourceList.Count;
}
else
{
HitBottomOfList = true;
}
}
}
bool handling = false;
public async void MyHandler()
{
// already handling an event, ignore the new one
if (handling) return;
handling = true;
await LoadTemplateList();
handling = false;
}
}
只需这样做
Command MyCommand = new Command(async () => await ExecuteMyCommand());
var myTask = LoadTemplateList();
Task.WaitAll(myTask); // This is blocking -