簡體   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