繁体   English   中英

C# 在继续之前等待异步方法完成

[英]C# Wait for async method to finish before continuing

我有个问题。 我为我的CollectionView创建了这个ViewModel

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;
}

这会检查是否已经有一个事件正在处理。

问题是在MyHandlerLoadTemplateList()不会等待结果,这会导致对我的网页进行多次调用,因为handling将立即设置为false

现在我如何等待LoadTemplateList()

您可能应该将Command with CanExecuteChangeCanExecute一起CanExecute ,如文档中所述

在订阅之前也可以通过-=取消订阅事件

您可以使命令异步并将等待的操作添加为

Command MyCommand = new Command(async () => await ExecuteMyCommand());

现在我如何等待 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;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM