зеркало из https://github.com/DeGsoft/maui-linux.git
[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
This commit is contained in:
Родитель
3716c57aab
Коммит
db4486db8f
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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" />
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче