【发布时间】:2015-10-15 23:27:33
【问题描述】:
我开发了一个使用 MVVM-Light 的通用应用程序。我从 ViewModels 调用 WebServices,并将 WebServices 调用遇到的异常抛出给 ViewModel:TimeOut、错误的 URL、服务器异常…… p>
我创建了一个类“ExceptionsMsgHelper.cs”,它通过MessageDialog集中显示每个异常的消息。
我的主页基于包含多个数据的 Pivot:一些 Web 服务是异步调用的。如果我通过类“ExceptionsMsgHelper.cs”在 MessageDialog 中显示异常,我会遇到崩溃,而之前的异常也显示在另一个 MessageDialog 中。
这是我原来的课程的一部分:
public class ExceptionsMsgHelper
{
public async static void MsgboxWebserviceErrors(WebServiceErrorsException wseE, string errors)
{
Windows.UI.Popups.MessageDialog msgbox =
new Windows.UI.Popups.MessageDialog("The Websercice '" + wseE.WebService + "' has returned errors : \n" + errors,
"Unexpected data");
await msgbox.ShowAsync();
}
}
=> 如果我调用两次“msgbox.ShowAsync()”,我得到“System.UnauthorizedAccessException”异常:带有消息“访问被拒绝。(来自 HRESULT 的异常:0x80070005 (E_ACCESSDENIED) )"
我一直在寻找解决方案来修复它:
- 使用“Dispatcter”,就像这里推荐的那样 (WinRT - MessageDialog.ShowAsync will throw UnauthorizedAccessException in my custom class)
代码是:
public class ExceptionsMsgHelper
{
public async static void MsgboxWebserviceErrors(WebServiceErrorsException wseE, string errors)
{
Windows.UI.Popups.MessageDialog msgbox =
new Windows.UI.Popups.MessageDialog("The Websercice '" + wseE.WebService + "' has returned errors : \n" + errors,
"Unexpected data");
CoreDispatcher dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
await msgbox.ShowAsync();
});
}
}
=>但我总是遇到同样的例外。
- 使用“IAsyncOperation”命令关闭之前的 MessageDialog,就像这里推荐的一样 (MessageDialog ShowAsync throws accessdenied exception on second dialog)
使用此代码:
public class ExceptionsMsgHelper
{
private static IAsyncOperation<IUICommand> messageDialogCommand = null;
public async static Task<bool> ShowDialog(MessageDialog dlg)
{
// Close the previous one out
if (messageDialogCommand != null)
{
messageDialogCommand.Cancel();
messageDialogCommand = null;
}
messageDialogCommand = dlg.ShowAsync();
await messageDialogCommand;
return true;
}
public async static void MsgboxWebserviceErrors(WebServiceErrorsException wseE, string errors)
{
Windows.UI.Popups.MessageDialog msgbox =
new Windows.UI.Popups.MessageDialog("The Websercice '" + wseE.WebService + "' has returned errors : \n" + errors,
"Unexpected data");
CoreDispatcher dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
await ShowDialog(msgbox);
});
}
}
=> 但在这种情况下,我也总是遇到同样的异常。
- 使用扩展程序将消息对话框排队,如在此处描述 (Multiple MessageDialog app crash)
现在的代码是:
public class ExceptionsMsgHelper
{
public async static void MsgboxWebserviceErrors(WebServiceErrorsException wseE, string errors)
{
Windows.UI.Popups.MessageDialog msgbox =
new Windows.UI.Popups.MessageDialog("The Websercice '" + wseE.WebService + "' has returned errors : \n" + errors,
"Unexpected data");
await MessageDialogExtensions.ShowAsyncQueue(msgbox);
}
}
public static class MessageDialogExtensions
{
private static TaskCompletionSource<MessageDialog> _currentDialogShowRequest;
public static async Task<IUICommand> ShowAsyncQueue(this MessageDialog dialog)
{
if (!Window.Current.Dispatcher.HasThreadAccess)
{
throw new InvalidOperationException("This method can only be invoked from UI thread.");
}
while (_currentDialogShowRequest != null)
{
await _currentDialogShowRequest.Task;
}
var request = _currentDialogShowRequest = new TaskCompletionSource<MessageDialog>();
var result = await dialog.ShowAsync();
_currentDialogShowRequest = null;
request.SetResult(dialog);
return result;
}
private static IAsyncOperation<IUICommand> messageDialogCommand = null;
public async static Task<bool> ShowDialog(this MessageDialog dlg)
{
// Close the previous one out
if (messageDialogCommand != null)
{
messageDialogCommand.Cancel();
messageDialogCommand = null;
}
messageDialogCommand = dlg.ShowAsync();
await messageDialogCommand;
return true;
}
#endregion
}
=>这对我有用。
但就像作者说的那样,这可能不是最好的解决方案:
当您需要打开一个新对话框时,请关闭现有对话框。这是最简单的选项,也可能是最好的选项,尽管您可能会取消一个可能很重要的对话,具体取决于您的对话内容。 排队对话,这样旧的对话就不会被解雇,但新的对话会在旧对话被解雇后出现。这将确保用户关闭所有对话框,但如果您的应用程序可以以某种方式开始显示数百个对话框,这可能是一个问题。 只有在没有显示的情况下才打开一个新的。现在这有可能不会显示更新的消息,这听起来比第一个选项更有问题。
=>我想了解为什么我不能应用似乎更适合的 2 个第一个解决方案
【问题讨论】:
标签: windows-phone-8.1 mvvm-light win-universal-app messagedialog windows-8.1-universal