diff options
author | Paul DiPietro <pauldipietro@users.noreply.github.com> | 2016-12-16 09:58:47 -0600 |
---|---|---|
committer | Rui Marinho <me@ruimarinho.net> | 2016-12-16 15:58:47 +0000 |
commit | db4486db8f41642dcd2948c929bee54500d23938 (patch) | |
tree | 1ab1b646ce0804781f2d00bd124c294ca0dce8c6 | |
parent | 3716c57aabc2407b02a8fd724d6ad9074e7b9d8f (diff) | |
download | xamarin-forms-db4486db8f41642dcd2948c929bee54500d23938.tar.gz xamarin-forms-db4486db8f41642dcd2948c929bee54500d23938.tar.bz2 xamarin-forms-db4486db8f41642dcd2948c929bee54500d23938.zip |
[WinRT] Use a queue to prevent multiple MessageDialogs from causing a crash (#347)
* [WinRT] Use a queue to prevent multiple MessageDialogs from causing a crash
* Make change to use Device.IsInvokeRequired
3 files changed, 73 insertions, 2 deletions
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla43469.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla43469.cs new file mode 100644 index 00000000..b81f98e3 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla43469.cs @@ -0,0 +1,37 @@ +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; +using System; +using System.Threading.Tasks; + +#if UITEST +using Xamarin.UITest; +using NUnit.Framework; +#endif + +namespace Xamarin.Forms.Controls +{ + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Bugzilla, 43469, "Calling DisplayAlert twice in WinRT causes a crash", PlatformAffected.WinRT)] + public class Bugzilla43469 : TestContentPage + { + protected override void Init() + { + var button = new Button { Text = "Click to call DisplayAlert twice" }; + + button.Clicked += (sender, args) => + { + Device.BeginInvokeOnMainThread(new Action(async () => + { + await DisplayAlert("First", "Text", "Cancel"); + })); + + Device.BeginInvokeOnMainThread(new Action(async () => + { + await DisplayAlert("Second", "Text", "Cancel"); + })); + }; + + Content = button; + } + } +}
\ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index 76c721f1..57f1cb83 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -131,6 +131,7 @@ <Compile Include="$(MSBuildThisFileDirectory)Bugzilla42364.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla42519.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla43313.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Bugzilla43469.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla43516.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla43663.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Bugzilla44944.cs" /> diff --git a/Xamarin.Forms.Platform.WinRT/Platform.cs b/Xamarin.Forms.Platform.WinRT/Platform.cs index d6a68fed..75dd772c 100644 --- a/Xamarin.Forms.Platform.WinRT/Platform.cs +++ b/Xamarin.Forms.Platform.WinRT/Platform.cs @@ -761,8 +761,41 @@ namespace Xamarin.Forms.Platform.WinRT dialog.CancelCommandIndex = (uint)dialog.Commands.Count - 1; } - IUICommand command = await dialog.ShowAsync(); - options.SetResult(command.Label == options.Accept); + if (Device.IsInvokeRequired) + { + Device.BeginInvokeOnMainThread(async () => + { + IUICommand command = await dialog.ShowAsyncQueue(); + options.SetResult(command.Label == options.Accept); + }); + } + else + { + IUICommand command = await dialog.ShowAsyncQueue(); + options.SetResult(command.Label == options.Accept); + } + } + } + + // refer to http://stackoverflow.com/questions/29209954/multiple-messagedialog-app-crash for why this is used + // in order to allow for multiple MessageDialogs, or a crash occurs otherwise + public static class MessageDialogExtensions + { + static TaskCompletionSource<MessageDialog> _currentDialogShowRequest; + + public static async Task<IUICommand> ShowAsyncQueue(this MessageDialog dialog) + { + while (_currentDialogShowRequest != null) + { + await _currentDialogShowRequest.Task; + } + + var request = _currentDialogShowRequest = new TaskCompletionSource<MessageDialog>(); + var result = await dialog.ShowAsync(); + _currentDialogShowRequest = null; + request.SetResult(dialog); + + return result; } } }
\ No newline at end of file |