我正在尝试在Windows 8中再次尝试/取消对话框。对话框第一次显示正常,但在再次单击尝试并再次失败时,我在调用ShowAsync时获得访问被拒绝的异常。 我不知道为什么,但奇怪的是,有时代码工作正常,当我放置断点时我没有得到异常。这里真的很无能
这是代码。
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();
}
}
答案 0 :(得分:25)
好的,我找到了一个快速解决方案,
定义IAsyncOperation类varialble
IAsyncOperation<IUICommand> asyncCommand = null;
并将其设置为MessageDialog的ShowAsync方法
asyncCommand = msg.ShowAsync();
在命令处理程序中重试/再试一次 检查asyncCommand是否为null,并在必要时取消上一次操作
if(asyncCommand != null)
{
asyncCommand.Cancel();
}
如果有更好的方法,请告诉我。
答案 1 :(得分:9)
我迟到了,但是这里可以随时等待对话框的结果,也不用担心连续调用太多:
首先在应用程序中定义一个静态变量和方法:
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;
}
现在,您可以传入任何对话框并始终等待执行。这就是为什么这会返回一个bool而不是void。您不必担心倍数之间的碰撞。为什么不让这个方法接受一个字符串?由于标题和是/否命令处理程序,您可以将其分配到正在使用的特定对话框中。
调用如:
await App.ShowDialog(new MessageDialog("FOO!"));
或
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);
答案 2 :(得分:3)
MSDN论坛上有一个答案可以帮到你。
我遇到了类似的问题,但我的showAsync调用是在不同的线程上的单独函数中,所以我不能在那里删除done()我不认为......
答案 3 :(得分:3)
我几天前遇到了同样的问题,我解决了等待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();
}
希望这有帮助!
答案 4 :(得分:1)
另一种解决方案:
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;
});
}