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

时间:2016-05-27 17:21:33

标签: c# mvvm dialog mahapps.metro continuations

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

然而,对于我的生活,我无法弄清楚如何做到这一点。我创建了一个类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); });
    }
}

我现在尝试使用continuation更改此设置,以便我可以获取用户选择的值,以便稍后从我的函数AbortPrintingDialog返回它。所以我修改了这样的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会锁定,我不会收到任何错误消息。那么我做错了什么?我一直试图解决这个问题并且在一段时间内摆弄它......

1 个答案:

答案 0 :(得分:1)

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

那你有什么选择?

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