1

我开发了一个使用MVVM-Light的通用应用程序。我从ViewModels调用WebServices,并将 WebServices 调用遇到的异常抛出给 ViewModels:TimeOut、Wrong URL、Server Exception,...

我创建了一个“ 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 个第一个解决方案

4

1 回答 1

2

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

如果关闭上一个对话框将是您的解决方案,请尝试ContentDialog改用MessageDialog. 检查我在本主题中的答案:在 WP 8.1 RT 中以编程方式关闭 MessageDialog

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

于 2015-10-16T06:42:26.093 回答