为什么这个C#代码不按顺序执行?不是ASYNC(至少我认为不是)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么这个C#代码不按顺序执行?不是ASYNC(至少我认为不是)相关的知识,希望对你有一定的参考价值。

任何人都可以帮我理解为什么在CanNavigateAway函数返回其值后我对dialogservice的调用会执行吗? (我的目标是警告用户他们即将离开视图而不保存他们的更改。如果他们单击OK,则允许导航。我正在使用MVVM Light。

当我单步执行代码时,它会到达对话框服务,但在创建对话框之前会进入CanNavigateAway的末尾。 CanNavigateAway方法由OnNavigatingFrom调用。

public bool CanNavigateAway()
    {
        if (!changesSaved && Model.IsModified && !continueNavigation)
        {             
              dialogService.ShowMessage("Are you sure you want to continue?",
              "Confirmation",
              buttonConfirmText: "Continue", buttonCancelText: "Discard",
              afterHideCallback: (confirmed) =>
              {
                  if (confirmed)
                  {
                      // User has pressed the "confirm" button.
                      // ...
                      continueNavigation = true;
                  }
                  else
                  {
                      // User has pressed the "cancel" button
                      // (or has discared the dialog box).
                      // ...
                      continueNavigation = false;
                  }
              });
            return continueNavigation;
        }
}

这是MVVM Light Bindable Page类中的OnNavigatingFrom方法:

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
    {
        var navigableViewModel = this.DataContext as INavigable;

        if (navigableViewModel != null)
        {
            if (!navigableViewModel.CanNavigateAway())
            {
                e.Cancel = true;
            }
        }
    }

我尝试了另一种方法来使对话框服务脱离混合,但showConfirmationDialogAsync似乎仍未及时执行:

public bool CanNavigateAway()
{
    continueNavigation = false;
    if (!changesSaved && Model.IsModified && !continueNavigation)
    {
        showConfirmationDialogAsync();
        return continueNavigation;
    }  

private async void showConfirmationDialogAsync()
{
    continueNavigation = false;
    ContentDialog noSaveConfirmation = new ContentDialog
    {
        Title = "Warning",
        Content = "You have unsaved changes. Are you sure you want to leave this page without saving?",
        PrimaryButtonText = "Leave without saving",
        SecondaryButtonText = "Stay and finish"
    };

    ContentDialogResult result = await noSaveConfirmation.ShowAsync();

    if (result == ContentDialogResult.Primary)
    {
        continueNavigation = true;
    }
    else if (result == ContentDialogResult.Secondary)
    {
        continueNavigation = false;
    }
}        
答案

如果您需要用户的回复,这些解决方案都不会起作用。问题是,当代码在导航事件处理程序中时,它在UI线程上运行,并且用户提示异步运行,以便UI可以自由地向用户显示对话框。但这意味着事件处理程序在用户有机会响应之前完成。

但是,您可以使用解决方法。添加一个标志bool字段,如forceNavigation。然后在OnNavigatingFrom内部向用户显示对话框并立即将Cancel设置为true并向用户显示确认对话框。如果用户说“是”,则将forceNavigaiton设置为true并再次手动触发导航。现在它将跳过确认部分并立即导航。

protected async override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{ 
    //if navigation is forced, skip all logic
    if ( !forceNavigation )
    {
        var navigableViewModel = this.DataContext as INavigable;

        if (navigableViewModel != null)
        {
            e.Cancel = true;
            //display the dialog to the user, if he says yes, set
            //forceNavigation = true; and repeat the navigation (e.g. GoBack, ... )
        }
    }
}

以上是关于为什么这个C#代码不按顺序执行?不是ASYNC(至少我认为不是)的主要内容,如果未能解决你的问题,请参考以下文章

async/await 函数不等待。多个功能不按顺序运行和完成

链式期货不按顺序执行

SIGSEGV:程序不按顺序执行

js 怎么让方法执行有先后顺序

@Async注解实现异步调用

Lua脚本不按顺序执行