Explorar el Código

Fixes #4208. MainLoopSyncContext doesn't work with the v2 drivers (#4209)

BDisp hace 1 mes
padre
commit
2025a81511

+ 15 - 8
Terminal.Gui/App/MainLoopSyncContext.cs

@@ -11,15 +11,22 @@ internal sealed class MainLoopSyncContext : SynchronizationContext
     public override void Post (SendOrPostCallback d, object state)
     {
         // Queue the task
-        Application.MainLoop?.TimedEvents.Add (TimeSpan.Zero,
-                                                      () =>
-                                                      {
-                                                          d (state);
+        if (ApplicationImpl.Instance.IsLegacy)
+        {
+            Application.MainLoop?.TimedEvents.Add (TimeSpan.Zero,
+                                                   () =>
+                                                   {
+                                                       d (state);
 
-                                                          return false;
-                                                      }
-                                                     );
-        Application.MainLoop?.Wakeup ();
+                                                       return false;
+                                                   }
+                                                  );
+            Application.MainLoop?.Wakeup ();
+        }
+        else
+        {
+            ApplicationImpl.Instance.Invoke (() => { d (state); });
+        }
     }
 
     //_mainLoop.Driver.Wakeup ();

+ 61 - 31
Tests/UnitTests/Application/SynchronizatonContextTests.cs

@@ -21,43 +21,73 @@ public class SyncrhonizationContextTests
         Application.Shutdown ();
     }
 
+    private object _lockPost = new ();
+
     [Theory]
     [InlineData (typeof (FakeDriver))]
     [InlineData (typeof (NetDriver))]
     [InlineData (typeof (WindowsDriver))]
     [InlineData (typeof (CursesDriver))]
-    public void SynchronizationContext_Post (Type driverType)
+    [InlineData (typeof (ConsoleDriverFacade<WindowsConsole.InputRecord>), "v2win")]
+    [InlineData (typeof (ConsoleDriverFacade<ConsoleKeyInfo>), "v2net")]
+    public void SynchronizationContext_Post (Type driverType, string driverName = null)
     {
-        ConsoleDriver.RunningUnitTests = true;
-        Application.Init (driverName: driverType.Name);
-        SynchronizationContext context = SynchronizationContext.Current;
-
-        var success = false;
-
-        Task.Run (
-                  () =>
-                  {
-                      Thread.Sleep (500);
-
-                      // non blocking
-                      context.Post (
-                                    delegate
-                                    {
-                                        success = true;
-
-                                        // then tell the application to quit
-                                        Application.Invoke (() => Application.RequestStop ());
-                                    },
-                                    null
-                                   );
-                      Assert.False (success);
-                  }
-                 );
-
-        // blocks here until the RequestStop is processed at the end of the test
-        Application.Run ().Dispose ();
-        Assert.True (success);
-        Application.Shutdown ();
+        lock (_lockPost)
+        {
+            ConsoleDriver.RunningUnitTests = true;
+
+            if (driverType.Name.Contains ("ConsoleDriverFacade"))
+            {
+                Application.Init (driverName: driverName);
+            }
+            else
+            {
+                Application.Init (driverName: driverType.Name);
+            }
+
+            SynchronizationContext context = SynchronizationContext.Current;
+
+            var success = false;
+
+            Task.Run (() =>
+                      {
+                          while (Application.Top is null || Application.Top is { Running: false })
+                          {
+                              Thread.Sleep (500);
+                          }
+
+                          // non blocking
+                          context.Post (
+                                        delegate
+                                        {
+                                            success = true;
+
+                                            // then tell the application to quit
+                                            Application.Invoke (() => Application.RequestStop ());
+                                        },
+                                        null
+                                       );
+
+                          if (Application.Top is { Running: true })
+                          {
+                              Assert.False (success);
+                          }
+                      }
+                     );
+
+            // blocks here until the RequestStop is processed at the end of the test
+            Application.Run ().Dispose ();
+            Assert.True (success);
+
+            if (ApplicationImpl.Instance is ApplicationV2)
+            {
+                ApplicationImpl.Instance.Shutdown ();
+            }
+            else
+            {
+                Application.Shutdown ();
+            }
+        }
     }
 
     [Fact]