【问题标题】:Multiple calls to MessageDialog cause crash under Windows Phone 8.1在 Windows Phone 8.1 下多次调用 MessageDialog 导致崩溃
【发布时间】: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) )"

我一直在寻找解决方案来修复它:

代码是:

    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();
            });
        }
    }

=>但我总是遇到同样的例外。

使用此代码:

    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);
            });
        }           
    }

=> 但在这种情况下,我也总是遇到同样的异常。

现在的代码是:

    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


    【解决方案1】:

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

    如果关闭上一个对话框对您来说是一种解决方案,请尝试使用ContentDialog 而不是MessageDialog。检查我在这个主题中的答案:Closing MessageDialog programatically in WP 8.1 RT

    我认为它解决了你的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多