【问题标题】:How to wait for a Navigation.PushAsync() task to complete before continue executing如何在继续执行之前等待 Navigation.PushAsync() 任务完成
【发布时间】:2018-01-05 17:16:54
【问题描述】:

我有以下代码:

 Task task = Navigation.PushAsync(myPage);
 foreach(var temp in myModel)
 {

      //do bla bla
 }

在我调用的页面上,当我完成所需的执行后,我会这样做:

this.Navigation.PopAsync();

问题是我只想在我的task 完成执行或我的myPage 完成执行之后执行我的for 循环。

我该如何解决这个问题?

【问题讨论】:

  • 您希望页面在循环开始之前执行特定任务,还是足以让它出现?您可以订阅 myPage 的“出现”事件,并在调用它时执行您的 for 循环。如果您的页面必须执行特定任务,您可以在页面上创建一个事件,这些事件将在这些任务完成后立即调用,并以与使用“Appearing”事件相同的方式使用它

标签: c# xamarin xamarin.forms navigation


【解决方案1】:

假设您在异步方法中,您可以将实现更改为

await Navigation.PushAsync(myPage)

然后继续你的 f​​or 循环。

如果您不在异步方法中,则可以调用该方法并通过调用 GetAwaiter().GetResult() 来强制阻塞等待;

Navigation.PushAsync(myPage).GetAwaiter().GetResult();

【讨论】:

  • for 循环在任务完成之前仍在执行。我猜 await Navigation.PushAsync(myPage) 刚刚调用或打开了我的页面,但它不会等待该任务完成,然后继续在当前页面上执行。
【解决方案2】:

您可以通过从页面的 OnDisapearing 方法调用事件来执行此操作,然后您创建的导航服务可以订阅此事件,然后您可以使用 "TaskCompletionSource" 来等待您的页面完成工作,然后完成任务。 有关完成此操作的更多详细信息,you can check this blog post.

以下是您应该使用的导航服务的概述:

public async Task<T> NavigateToModal<T>(string modalName)
    {
        var source = new TaskCompletionSource<T>();
        if (modalName == nameof(NewItemPage))
        {
            var page = new NewItemPage();
            page.PageDisapearing += (result) =>
            {
                var res = (T)Convert.ChangeType(result, typeof(T));
                source.SetResult(res);
            };
            await App.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page));
        }
        return await source.Task;
    }

【讨论】:

    【解决方案3】:

    如果我没听错的话,你希望在执行 this.Navigation.PopAsync() 之后执行 foreach 循环。对吧?

    我会提出以下方法之一:

    1) 在(推送)myPage 上执行任务PopAsync():您可以将对象中所需的任何数据(例如myModel)交给myPage 并执行循环在

    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        foreach(var temp in myModel)
        {
             //do bla bla
        }
    }
    

    2)您在原始页面上设置了一个标志,该标志已被pushAsync(myPage) 隐藏,并在重新出现后执行您的代码。

    bool pushStarted;
    
    protected void YourMethod()
    {
        pushStarted = true;
        await Navigation.PushAsync(myPage);
    }
    
    protected override void OnAppearing()
    {
        base.OnAppearing();
        if(pushStarted)
        {
            pushStarted = false;
            foreach(var temp in myModel)
            {
                 //do bla bla
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-16
      • 2020-02-24
      • 1970-01-01
      • 1970-01-01
      • 2016-08-31
      相关资源
      最近更新 更多