如何使用任务继续从 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
是如何在内部实现的。当然,这个库的开发人员应该为您提供一种同步调用该方法的方法,但他们没有,所以您不得不忍受这个。
那你有什么选择?
- 使用任务延续。为此,您需要重写使用 AbortPrintingDialog 的代码,但您已经知道了。
- 升级到更新的框架版本并使用 async\await 功能。
- 安装 this 包并使用 .NET 4 中的 async\await 功能。
我正在使用 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
是如何在内部实现的。当然,这个库的开发人员应该为您提供一种同步调用该方法的方法,但他们没有,所以您不得不忍受这个。
那你有什么选择?
- 使用任务延续。为此,您需要重写使用 AbortPrintingDialog 的代码,但您已经知道了。
- 升级到更新的框架版本并使用 async\await 功能。
- 安装 this 包并使用 .NET 4 中的 async\await 功能。