windows MessageDialog ShowAsync 在第二个对话框中抛出 accessdenied 异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12722490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MessageDialog ShowAsync throws accessdenied exception on second dialog
提问by Syler
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
我正在尝试在 Windows 8 中实现重试/取消对话框。该对话框第一次显示正常,但在单击重试并再次失败时,我在调用 ShowAsync 时遇到访问被拒绝异常。我不知道为什么,但奇怪的是有时代码运行良好,当我放置断点时我没有收到异常。这里真的一无所知
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();
}
}
回答by Syler
Okay I found a quick solution,
好的,我找到了一个快速解决方案,
define a IAsyncOperation class varialble
定义一个 IAsyncOperation 类变量
IAsyncOperation<IUICommand> asyncCommand = null;
and set it to the ShowAsync method of MessageDialog
并将其设置为 MessageDialog 的 ShowAsync 方法
asyncCommand = msg.ShowAsync();
In the command handler for retry/try again check if asyncCommand is not null and cancel the last operation if necessary
在重试/重试的命令处理程序中检查 asyncCommand 是否不为 null 并在必要时取消最后一个操作
if(asyncCommand != null)
{
asyncCommand.Cancel();
}
Please let me if there is a better approach to this.
如果有更好的方法,请告诉我。
回答by Paul
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.
现在,您可以传入任何对话框并始终等待执行。这就是为什么它返回一个 bool 而不是 void。您不必担心倍数之间的冲突。为什么不让这个方法接受一个字符串?由于标题和是/否命令处理程序,您可以分配到您正在使用的特定对话框中。
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);
回答by Real World
There is an answer for this on the MSDN forums that might help you here.
在 MSDN 论坛上有一个答案,可能对您有所帮助。
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...
我有一个类似的问题,但我的 showAsync 调用在不同线程上的不同函数中,所以我不能在那里删除 done() 我不认为......
回答by Rafael Pe?a García
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.
几天前我遇到了同样的问题,我解决了它,等待 ShowAsync,然后进行递归调用,再次打开 MessageDialog。
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!
希望这有帮助!
回答by Tonatio
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;
});
}

