MessageDialog ShowAsync throws accessdenied exception on second dialog
Solution 1
Okay I found a quick solution,
define a IAsyncOperation class varialble
IAsyncOperation<IUICommand> asyncCommand = null;
and set it to the ShowAsync method of MessageDialog
asyncCommand = msg.ShowAsync();
In the command handler for retry/try again check if asyncCommand is not null and cancel the last operation if necessary
if(asyncCommand != null)
{
asyncCommand.Cancel();
}
Please let me if there is a better approach to this.
Solution 2
I am late to the party, but here's a way where you can always await the result of the dialog box, as well as not need to worry about calling too many in a row:
First define a static variable and method in your application:
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;
}
Now, you can pass in any dialog box and always await execution. This is why this returns a bool rather than void. You won't have to worry about collisions between multiples. Why not make this method accept a string? Because of title, and Yes/No command handlers that you may assign into the specific dialog box you are using.
Invoke such as:
await App.ShowDialog(new MessageDialog("FOO!"));
or
var dlg = new MessageDialog("FOO?", "BAR?");
dlg.Commands.Add(new UICommand("Yes", new UICommandInvokedHandler(YesHandler)));
dlg.Commands.Add(new UICommand("No", new UICommandInvokedHandler(NoHandler)));
await App.ShowDialog(dlg);
Solution 3
There is an answer for this on the MSDN forums that might help you here.
I'm having a similar problem but my showAsync calls are in separate functions on separate threads so I can't drop a done() in there I don't think...
Solution 4
I was facing this same issue some days ago, and i solve it awaiting the ShowAsync and then making the recursive call that open the MessageDialog again.
public async void ShowDlg(){
Action cmdAction = null;
var msgDlg = new MessageDialog("Content.", "Title");
msgDlg.Commands.Add(new UICommand("Retry", (x) => {
cmdAction = () => ShowDlg();
}));
msgDlg.Commands.Add(new UICommand("Cancel", (x) => {
cmdAction = () => <Action associated with the cancel button>;
}));
msgDlg.DefaultCommandIndex = 0;
msgDlg.CancelCommandIndex = 1;
await msgDlg.ShowAsync();
cmdAction.Invoke();
}
Hope this help!
Solution 5
Another solution:
private bool _messageShowing = false;
// ...
if (!_messageShowing)
{
_messageShowing = true;
var messageDialog = new MessageDialog("Example");
// ... "messageDialog" initialization
Task<IUICommand> showMessageTask = messageDialog.ShowAsync().AsTask();
await showMessageTask.ContinueWith((showAsyncResult) =>
{
_messageShowing = false;
});
}
Related videos on Youtube
Syler
Updated on June 12, 2020Comments
-
Syler about 4 years
I am trying to implement try again/cancel dialog box in windows 8. The dialog box shows fine the first time, but on clicking try again and failing again, I get a access denied exception on calling ShowAsync. I don't know why, but its strange sometimes the code works fine and I don't get the exception when I put breakpoints. really clueless here
here is the code.
async void DismissedEventHandler(SplashScreen sender, object e) { dismissed = true; loadFeeds(); } private async void loadFeeds() { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => { try { RSSDataSource rssDataSource = (RSSDataSource)App.Current.Resources["RSSDataSource"]; if (rssDataSource != null) { await rssDataSource.DownloadFeeds(); await rssDataSource.GetFeedsAsync(); } AdDataSource ads = (AdDataSource)App.Current.Resources["AdDataSource"]; if (ads != null) { await ads.DownloadAds(); } rootFrame.Navigate(typeof(HomePageView)); Window.Current.Content = rootFrame; } catch { ShowError(); } }); } async void ShowError() { // There was likely a problem initializing MessageDialog msg = new MessageDialog(CONNECTION_ERROR_MESSAGE, CONNECTION_ERROR_TITLE); // Add buttons and set their command handlers msg.Commands.Add(new UICommand(COMMAND_LABEL_RETRY, new UICommandInvokedHandler(this.CommandInvokedHandler))); msg.Commands.Add(new UICommand(COMMAND_LABEL_CLOSE, new UICommandInvokedHandler(this.CommandInvokedHandler))); // Set the command to be invoked when a user presses 'ESC' msg.CancelCommandIndex = 0; await msg.ShowAsync(); } /// <summary> /// Callback function for the invocation of the dialog commands /// </summary> /// <param name="command">The command that was invoked</param> private void CommandInvokedHandler(IUICommand command) { string buttonLabel = command.Label; if (buttonLabel.Equals(COMMAND_LABEL_RETRY)) { loadFeeds(); } else { // Close app Application.Current.Exit(); } }
-
Syler over 11 yearstry using an instance variable and hold a reference to the asyncCommand and check if the command is not null. it might work.
-
B. Clay Shannon-B. Crow Raven over 11 yearsTo prevent getting "Use of unassigned local variable 'asyncCommand'", I had to assign null to asyncCommand when it is assigned.
-
RelativeGames over 10 yearsSide note : I had my own task que running in a single thread and I was only doing ONE ShowAsync from ONE thread at a time. Apparently if one ShowAsync ends in frame 1 and a second ShowAsync starts in frame 2, a random Access Denied error can pop :/. Manually canceling works though.
-
Chris Bordeman about 9 yearsThis works perfectly in my scenario where the second dialog was not really nested, but instead shown in the callback action of the first UICommand.