如何使用任务继续从 MahApps 获取对话框的用户选择

How to get the user-slection of a dialog from MahApps using task continuation

我正在使用 MahApps,我正在尝试在用户取消打印过程时实施中止对话框。由于我仍在使用 .Net 4.0,因此我无法使用 await,但需要按照 here:

所述使用延续

然而,对于我的生活,我无法弄清楚如何做到这一点。我创建了一个 class DialogService,我想在需要时使用它来显示对话框。我添加了方法 AbortPrintingDialog(ViewModelBase parentViewModel),其中 parentViewModel 是要显示对话框的 ViewModel。最初我有以下 AbortPrintingDialog,这是对 MahApps 示例程序代码的改编,并按预期工作,在调试控制台上给出正确的输出:

public class DialogService
{
    private IDialogCoordinator dialogCoordinator;

    public DialogService(IDialogCoordinator dialogCoordinator)
    {
        this.dialogCoordinator = dialogCoordinator;
    }

    public void AbortPrintingDialog(ViewModelBase parentViewModel)
    {
        dialogCoordinator.ShowMessageAsync(parentViewModel,
                        "Abort Printing",
                        "Printing is in progress. Are you sure you want to abort the printing process?",
                        MessageDialogStyle.AffirmativeAndNegative).ContinueWith(t => { Debug.WriteLine("t.Result: " + t.Result); });
    }
}

我现在尝试使用延续来更改它,以便我可以获取用户选择的值,以便稍后从我的函数 AbortPrintingDialog 中 return 它。所以我像这样修改了 AbortPrintingDialog ,我认为在阅读了这个 MSDN page:

的代码后会起作用
public MessageDialogResult AbortPrintingDialog(ViewModelBase parentViewModel)
{
    Task<MessageDialogResult> WaitUserInputTask = dialogCoordinator.ShowMessageAsync(parentViewModel,
                        "Abort Printing",
                        "Printing is in progress. Are you sure you want to abort the printing process?",
                        MessageDialogStyle.AffirmativeAndNegative);
    Task.WaitAll(WaitUserInputTask);
    Task<MessageDialogResult> continuation = WaitUserInputTask.ContinueWith((antecedent) =>
     {
         return antecedent.Result;
     });

    return continuation.Result;
}

但是,现在当我在我的 GUI 中点击中止按钮来调用 AbortPrintingDialog 时,GUI 锁定并且我没有收到任何错误消息。那我做错了什么?我一直在努力解决这个问题并摆弄了一段时间......

我会试着解释一下为什么你不能完全按照你的意愿去做。首先,为什么你的代码会死锁。当用户做出选择并且 dialogCoordinator.ShowMessageAsync 中的某些内部代码需要继续时 - 它会在 UI(用户界面)线程上执行。但是您已经阻塞了 UI 线程 - 您正在等待 dialogCoordinator.ShowMessageAsync 完成 。所以你只是 不能 在 UI 线程上等待 ShowMessageAsync 完成,因为 ShowMessageAsync 是如何在内部实现的。当然,这个库的开发人员应该为您提供一种同步调用该方法的方法,但他们没有,所以您不得不忍受这个。

那你有什么选择?

  1. 使用任务延续。为此,您需要重写使用 AbortPrintingDialog 的代码,但您已经知道了。
  2. 升级到更新的框架版本并使用 async\await 功能。
  3. 安装 this 包并使用 .NET 4 中的 async\await 功能。