Windows phone 8.1 在Windows Phone 8.1下,多次调用MessageDialog会导致崩溃

Windows phone 8.1 在Windows Phone 8.1下,多次调用MessageDialog会导致崩溃,windows-phone-8.1,mvvm-light,win-universal-app,messagedialog,windows-8.1-universal,Windows Phone 8.1,Mvvm Light,Win Universal App,Messagedialog,Windows 8.1 Universal,我开发了一个通用应用程序,它使用MVVM Light。我从ViewModels调用WebServices,并将调用WebServices时遇到的异常抛出到ViewModels:超时、错误URL、服务器异常 我创建了一个类“ExceptionsMsgHelper.cs”,它通过MessageDialog集中显示每个异常的消息 我的主页基于一个包含多个数据的透视:一些Web服务被异步调用。因此,如果我通过类“ExceptionsMsgHelper.cs”在MessageDialog中显示异常,则会遇

我开发了一个通用应用程序,它使用MVVM Light。我从ViewModels调用WebServices,并将调用WebServices时遇到的异常抛出到ViewModels:超时、错误URL、服务器异常

我创建了一个类“ExceptionsMsgHelper.cs”,它通过MessageDialog集中显示每个异常的消息

我的主页基于一个包含多个数据的透视:一些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.showsync()”,我会得到“System.UnauthorizedAccessException”异常:消息为“访问被拒绝”(来自HRESULT的异常:0x80070005(E_ACCESSDENIED))”

为了解决这个问题,我一直在寻找解决方案:

  • 使用“dispatacter”,就像这里推荐的那样()
代码是:

    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”命令关闭上一个消息对话框,如此处推荐的()
使用此代码:

    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);
            });
        }           
    }
公共类例外msghelper
{
私有静态IAsyncOperation messageDialogCommand=null;
公共异步静态任务ShowDialog(MessageDialog dlg)
{
//关闭前一个
if(messageDialogCommand!=null)
{
messageDialogCommand.Cancel();
messageDialogCommand=null;
}
messageDialogCommand=dlg.ShowAsync();
等待消息对话框命令;
返回true;
}
公共异步静态void MsgboxWebserviceErrors(WebServiceErrorsException wseE,字符串错误)
{
Windows.UI.Popups.MessageDialog msgbox=
新的Windows.UI.Popups.MessageDialog(“Webercice'+wseE.WebService+”'返回了错误:\n“+错误,
“意外数据”);
CoreDispatcher dispatcher=CoreWindow.GetForCurrentThread().dispatcher;
dispatcher.RunAsync(CoreDispatcherPriority.Normal,async()=>
{
等待显示对话框(msgbox);
});
}           
}
=>但是在这种情况下,我也总是得到同样的异常。

  • 使用扩展来排队消息对话框,如下所述()
代码现在是:

    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
    }
公共类例外msghelper
{
公共异步静态void MsgboxWebserviceErrors(WebServiceErrorsException wseE,字符串错误)
{
Windows.UI.Popups.MessageDialog msgbox=
新的Windows.UI.Popups.MessageDialog(“Webercice'+wseE.WebService+”'返回了错误:\n“+错误,
“意外数据”);
等待MessageDialogExtensions.ShowAsyncQueue(msgbox);
}
}
公共静态类MessageDialogExtensions
{
私有静态任务完成源\u currentDialogShowRequest;
公共静态异步任务ShowAsyncQueue(此消息对话框)
{
如果(!Window.Current.Dispatcher.HasThreadAccess)
{
抛出新的InvalidOperationException(“此方法只能从UI线程调用”);
}
while(_currentDialogShowRequest!=null)
{
等待_currentDialogShowRequest.Task;
}
var request=_currentDialogShowRequest=new TaskCompletionSource();
var result=wait dialog.ShowAsync();
_currentDialogShowRequest=null;
request.SetResult(对话框);
返回结果;
}
私有静态IAsyncOperation messageDialogCommand=null;
公共异步静态任务ShowDialog(此MessageDialog dlg)
{
//关闭前一个
if(messageDialogCommand!=null)
{
messageDialogCommand.Cancel();
messageDialogCommand=null;
}
messageDialogCommand=dlg.ShowAsync();
等待消息对话框命令;
返回true;
}
#端区
}
=>这对我很有用。

但正如作者所说,这可能不是最好的解决方案:

需要打开新对话框时,请关闭现有对话框。这是最简单的选择,也可能是最好的选择,尽管您可能会取消一个对话框,而这个对话框可能在某种程度上很重要,这取决于您的对话框是关于什么的。 对对话框进行排队,以便旧对话框不会被取消,但新对话框会在旧对话框取消后显示。这将确保用户关闭所有对话框,但如果你的应用程序能够以某种方式开始显示数百个对话框,那么这可能是一个问题。 只有在没有显示的情况下才打开一个新的。现在,这样做的风险是没有显示新的消息,这听起来比第一个选项更有问题


=>我想了解为什么我不能应用前两种似乎更适合的解决方案之一

当然,您不能同时显示两个或更多的消息对话框(windows phone限制)。此外,Windows Phone 8.1上的
MessageDialog
可能存在错误,无法关闭

如果关闭上一个对话框是您的解决方案,请尝试使用
ContentDialog
而不是
MessageDialog
。检查我在本主题中的答案:

我想这能解决你的问题