Prevent UWP NullReferenceException when calling SavePropertiesAsync method off the...
authorTomáš Ondřej <45392392+TomOnd@users.noreply.github.com>
Wed, 4 Dec 2019 16:56:23 +0000 (17:56 +0100)
committerShane Neuville <shneuvil@microsoft.com>
Wed, 4 Dec 2019 16:56:23 +0000 (09:56 -0700)
* Fix Issue 8682

* Rename UI test method

Co-Authored-By: Samantha Houts <samhouts@users.noreply.github.com>
* Return FallbackDispatcher with null-coalescing

Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue8682.cs [new file with mode: 0644]
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
Xamarin.Forms.Core/DispatcherExtensions.cs

diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue8682.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue8682.cs
new file mode 100644 (file)
index 0000000..50039fe
--- /dev/null
@@ -0,0 +1,81 @@
+using System;
+using System.Threading.Tasks;
+using Xamarin.Forms.CustomAttributes;
+using Xamarin.Forms.Internals;
+
+#if UITEST
+using Xamarin.Forms.Core.UITests;
+using Xamarin.UITest;
+using NUnit.Framework;
+#endif
+
+namespace Xamarin.Forms.Controls.Issues
+{
+#if UITEST
+       [Category(UITestCategories.ManualReview)]
+#endif
+       [Preserve(AllMembers = true)]
+       [Issue(IssueTracker.Github, 8682, "[Bug] [UWP] NullReferenceException when call SavePropertiesAsync method off the main thread", PlatformAffected.UWP)]
+       public class Issue8682 : TestContentPage
+       {
+               const string Run = "Save properties";
+               const string Success = "Success";
+
+               Label _result;
+
+               protected override void Init()
+               {
+                       var instructions = new Label
+                       {
+                               Text = $"Tap the button marked {Run}. If the Label below reads {Success} then the test has passed."
+                       };
+
+                       _result = new Label();
+
+                       var testButton = new Button
+                       {
+                               Text = Run
+                       };
+                       testButton.Clicked += OnTestButtonClicked;
+
+                       var layout = new StackLayout();
+                       layout.Children.Add(instructions);
+                       layout.Children.Add(_result);
+                       layout.Children.Add(testButton);
+
+                       Content = layout;
+               }
+
+               async void OnTestButtonClicked(object sender, EventArgs e)
+               {
+                       _result.Text = await SavePropertiesAsyncOffMainThread();
+               }
+
+               async Task<string> SavePropertiesAsyncOffMainThread()
+               {
+                       return await Task.Run(async () => 
+                       {
+                               try
+                               {
+                                       await Application.Current.SavePropertiesAsync();
+
+                                       return Success;
+                               } 
+                               catch (Exception e)
+                               {
+                                       return $"Test failed: {e.Message}.";
+                               }
+                       });
+               }
+
+#if UITEST
+               [Test]
+               public void SavePropertiesAsyncOffMainThreadDoesNotCrash() 
+               {
+                       RunningApp.WaitForElement(Run);
+                       RunningApp.Tap(Run);
+                       RunningApp.WaitForElement(Success);
+               }
+#endif
+       }
+}
index 6e3464d..a66867b 100644 (file)
       <DependentUpon>Github5623.xaml</DependentUpon>
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="$(MSBuildThisFileDirectory)Issue8682.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Bugzilla59172.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)FlagTestHelpers.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue5886.cs" />
index f5de449..73d6f31 100644 (file)
@@ -26,7 +26,7 @@ namespace Xamarin.Forms
                        }
 
                        // Use the DispatcherProvider to retrieve an appropriate dispatcher for this BindableObject
-                       return s_current.GetDispatcher(bindableObject);
+                       return s_current.GetDispatcher(bindableObject) ?? new FallbackDispatcher();
                }
 
                public static void Dispatch(this IDispatcher dispatcher, Action action)