| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 | 
							- using System;
 
- using System.Threading;
 
- using System.Threading.Tasks;
 
- using Avalonia.Controls.Platform;
 
- using Avalonia.Threading;
 
- using Xunit;
 
- namespace Avalonia.Base.UnitTests;
 
- // Some of these exceptions are based from https://github.com/dotnet/wpf-test/blob/05797008bb4975ceeb71be36c47f01688f535d53/src/Test/ElementServices/FeatureTests/Untrusted/Dispatcher/UnhandledExceptionTest.cs#L30
 
- public partial class DispatcherTests
 
- {
 
-     private const string ExpectedExceptionText = "Exception thrown inside Dispatcher.Invoke / Dispatcher.BeginInvoke.";
 
-     private int _numberOfHandlerOnUnhandledEventInvoked;
 
-     private int _numberOfHandlerOnUnhandledEventFilterInvoked;
 
-     public DispatcherTests()
 
-     {
 
-         _numberOfHandlerOnUnhandledEventInvoked = 0;
 
-         _numberOfHandlerOnUnhandledEventFilterInvoked = 0;
 
-     }
 
-     [Fact]
 
-     public void DispatcherHandlesExceptionWithPost()
 
-     {
 
-         var impl = new ManagedDispatcherImpl(null);
 
-         var disp = new Dispatcher(impl);
 
-         var handled = false;
 
-         var executed = false;
 
-         disp.UnhandledException += (sender, args) =>
 
-         {
 
-             handled = true;
 
-             args.Handled = true;
 
-         };
 
-         disp.Post(() => ThrowAnException());
 
-         disp.Post(() => executed = true);
 
-         disp.RunJobs();
 
-         
 
-         Assert.True(handled);
 
-         Assert.True(executed);
 
-     }
 
-     [Fact]
 
-     public void SyncContextExceptionCanBeHandledWithPost()
 
-     {
 
-         var impl = new ManagedDispatcherImpl(null);
 
-         var disp = new Dispatcher(impl);
 
-         var syncContext = disp.GetContextWithPriority(DispatcherPriority.Background);
 
-         var handled = false;
 
-         var executed = false;
 
-         disp.UnhandledException += (sender, args) =>
 
-         {
 
-             handled = true;
 
-             args.Handled = true;
 
-         };
 
-         syncContext.Post(_ => ThrowAnException(), null);
 
-         syncContext.Post(_ => executed = true, null);
 
-         disp.RunJobs();
 
-         Assert.True(handled);
 
-         Assert.True(executed);
 
-     }
 
-     [Fact]
 
-     public void CanRemoveDispatcherExceptionHandler()
 
-     {
 
-         var impl = new ManagedDispatcherImpl(null);
 
-         var dispatcher = new Dispatcher(impl);
 
-         var caughtCorrectException = false;
 
-         dispatcher.UnhandledExceptionFilter +=
 
-             HandlerOnUnhandledExceptionFilterRequestCatch;
 
-         dispatcher.UnhandledException +=
 
-             HandlerOnUnhandledExceptionNotHandled;
 
-         dispatcher.UnhandledExceptionFilter -=
 
-             HandlerOnUnhandledExceptionFilterRequestCatch;
 
-         dispatcher.UnhandledException -=
 
-             HandlerOnUnhandledExceptionNotHandled;
 
-         try
 
-         {
 
-             dispatcher.Post(ThrowAnException, DispatcherPriority.Normal);
 
-             dispatcher.RunJobs();
 
-         }
 
-         catch (Exception e)
 
-         {
 
-             caughtCorrectException = e.Message == ExpectedExceptionText;
 
-         }
 
-         finally
 
-         {
 
-             Verification(caughtCorrectException, 0, 0);
 
-         }
 
-     }
 
-     [Fact]
 
-     public void CanHandleExceptionWithUnhandledException()
 
-     {
 
-         var impl = new ManagedDispatcherImpl(null);
 
-         var dispatcher = new Dispatcher(impl);
 
-         
 
-         dispatcher.UnhandledExceptionFilter +=
 
-             HandlerOnUnhandledExceptionFilterRequestCatch;
 
-         
 
-         dispatcher.UnhandledException +=
 
-             HandlerOnUnhandledExceptionHandled;
 
-         var caughtCorrectException = true;
 
-         try
 
-         {
 
-             dispatcher.Post(ThrowAnException, DispatcherPriority.Normal);
 
-             dispatcher.RunJobs();
 
-         }
 
-         catch (Exception)
 
-         {
 
-             // should be no exception here.
 
-             caughtCorrectException = false;
 
-         }
 
-         finally
 
-         {
 
-             Verification(caughtCorrectException, 1, 1);
 
-         }
 
-     }
 
-     [Fact]
 
-     public void InvokeMethodDoesntTriggerUnhandledException()
 
-     {
 
-         var impl = new ManagedDispatcherImpl(null);
 
-         var dispatcher = new Dispatcher(impl);
 
-         
 
-         dispatcher.UnhandledExceptionFilter +=
 
-             HandlerOnUnhandledExceptionFilterRequestCatch;
 
-         
 
-         dispatcher.UnhandledException +=
 
-             HandlerOnUnhandledExceptionHandled;
 
-         var caughtCorrectException = false;
 
-         try
 
-         {
 
-             // Since both Invoke and InvokeAsync can throw exception, there is no need to pass them to the UnhandledException.
 
-             dispatcher.Invoke(ThrowAnException, DispatcherPriority.Normal);
 
-             dispatcher.RunJobs();
 
-         }
 
-         catch (Exception e)
 
-         {
 
-             // should be no exception here.
 
-             caughtCorrectException = e.Message == ExpectedExceptionText;
 
-         }
 
-         finally
 
-         {
 
-             Verification(caughtCorrectException, 0, 0);
 
-         }
 
-     }
 
-     [Fact]
 
-     public void InvokeAsyncMethodDoesntTriggerUnhandledException()
 
-     {
 
-         var impl = new ManagedDispatcherImpl(null);
 
-         var dispatcher = new Dispatcher(impl);
 
-         
 
-         dispatcher.UnhandledExceptionFilter +=
 
-             HandlerOnUnhandledExceptionFilterRequestCatch;
 
-         
 
-         dispatcher.UnhandledException +=
 
-             HandlerOnUnhandledExceptionHandled;
 
-         var caughtCorrectException = false;
 
-         try
 
-         {
 
-             // Since both Invoke and InvokeAsync can throw exception, there is no need to pass them to the UnhandledException.
 
-             var op = dispatcher.InvokeAsync(ThrowAnException, DispatcherPriority.Normal);
 
-             op.Wait();
 
-             dispatcher.RunJobs();
 
-         }
 
-         catch (Exception e)
 
-         {
 
-             // should be no exception here.
 
-             caughtCorrectException = e.Message == ExpectedExceptionText;
 
-         }
 
-         finally
 
-         {
 
-             Verification(caughtCorrectException, 0, 0);
 
-         }
 
-     }
 
-     [Fact]
 
-     public void CanRethrowExceptionWithUnhandledException()
 
-     {
 
-         var impl = new ManagedDispatcherImpl(null);
 
-         var dispatcher = new Dispatcher(impl);
 
-         
 
-         dispatcher.UnhandledExceptionFilter +=
 
-             HandlerOnUnhandledExceptionFilterRequestCatch;
 
-         
 
-         dispatcher.UnhandledException +=
 
-             HandlerOnUnhandledExceptionNotHandled;
 
-         var caughtCorrectException = false;
 
-         try
 
-         {
 
-             dispatcher.Post(ThrowAnException, DispatcherPriority.Normal);
 
-             dispatcher.RunJobs();
 
-         }
 
-         catch (Exception e)
 
-         {
 
-             caughtCorrectException = e.Message == ExpectedExceptionText;
 
-         }
 
-         finally
 
-         {
 
-             Verification(caughtCorrectException, 1, 1);
 
-         }
 
-     }
 
-     [Fact]
 
-     public void MultipleUnhandledExceptionFilterCannotResetRequestCatchFlag()
 
-     {
 
-         var impl = new ManagedDispatcherImpl(null);
 
-         var dispatcher = new Dispatcher(impl);
 
-         
 
-         dispatcher.UnhandledExceptionFilter +=
 
-             HandlerOnUnhandledExceptionFilterNotRequestCatch;
 
-         dispatcher.UnhandledExceptionFilter +=
 
-             HandlerOnUnhandledExceptionFilterRequestCatch;
 
-         
 
-         dispatcher.UnhandledException +=
 
-             HandlerOnUnhandledExceptionNotHandled;
 
-         dispatcher.UnhandledException +=
 
-             HandlerOnUnhandledExceptionHandled;
 
-         var caughtCorrectException = false;
 
-         try
 
-         {
 
-             dispatcher.Post(ThrowAnException, DispatcherPriority.Normal);
 
-             dispatcher.RunJobs();
 
-         }
 
-         catch (Exception e)
 
-         {
 
-             caughtCorrectException = e.Message == ExpectedExceptionText;
 
-         }
 
-         finally
 
-         {
 
-             Verification(caughtCorrectException, 0, 2);
 
-         }
 
-     }
 
-     [Fact]
 
-     public void MultipleUnhandledExceptionCannotResetHandleFlag()
 
-     {
 
-         var impl = new ManagedDispatcherImpl(null);
 
-         var dispatcher = new Dispatcher(impl);
 
-         
 
-         dispatcher.UnhandledExceptionFilter +=
 
-             HandlerOnUnhandledExceptionFilterRequestCatch;
 
-         
 
-         dispatcher.UnhandledException +=
 
-             HandlerOnUnhandledExceptionHandled;
 
-         dispatcher.UnhandledException +=
 
-             HandlerOnUnhandledExceptionNotHandled;
 
-         var caughtCorrectException = true;
 
-         
 
-         try
 
-         {
 
-             dispatcher.Post(ThrowAnException, DispatcherPriority.Normal);
 
-             dispatcher.RunJobs();
 
-         }
 
-         catch (Exception)
 
-         {
 
-             // should be no exception here.
 
-             caughtCorrectException = false;
 
-         }
 
-         finally
 
-         {
 
-             Verification(caughtCorrectException, 1, 1);
 
-         }
 
-     }
 
-     [Fact]
 
-     public void CanPushFrameAndShutdownDispatcherFromUnhandledException()
 
-     {
 
-         var impl = new ManagedDispatcherImpl(null);
 
-         var dispatcher = new Dispatcher(impl);
 
-         
 
-         dispatcher.UnhandledExceptionFilter +=
 
-             HandlerOnUnhandledExceptionFilterNotRequestCatchPushFrame;
 
-         
 
-         dispatcher.UnhandledException +=
 
-             HandlerOnUnhandledExceptionHandledPushFrame;
 
-         var caughtCorrectException = false;
 
-         try
 
-         {
 
-             dispatcher.Post(ThrowAnException, DispatcherPriority.Normal);
 
-             dispatcher.RunJobs();
 
-         }
 
-         catch (Exception e)
 
-         {
 
-             caughtCorrectException = e.Message == ExpectedExceptionText;
 
-         }
 
-         finally
 
-         {
 
-             Verification(caughtCorrectException, 0, 1);
 
-         }
 
-     }
 
-     
 
-     private void Verification(bool caughtCorrectException, int numberOfHandlerOnUnhandledEventShouldInvoke,
 
-         int numberOfHandlerOnUnhandledEventFilterShouldInvoke)
 
-     {
 
-         Assert.True(
 
-             _numberOfHandlerOnUnhandledEventInvoked >= numberOfHandlerOnUnhandledEventShouldInvoke,
 
-             "Number of handler invoked on UnhandledException is invalid");
 
-         Assert.True(
 
-             _numberOfHandlerOnUnhandledEventFilterInvoked >= numberOfHandlerOnUnhandledEventFilterShouldInvoke,
 
-             "Number of handler invoked on UnhandledExceptionFilter is invalid");
 
-         Assert.True(caughtCorrectException, "Wrong exception caught.");
 
-     }
 
-     private void HandlerOnUnhandledExceptionFilterRequestCatch(object sender,
 
-         DispatcherUnhandledExceptionFilterEventArgs args)
 
-     {
 
-         args.RequestCatch = true;
 
-         _numberOfHandlerOnUnhandledEventFilterInvoked += 1;
 
-         Assert.Equal(ExpectedExceptionText, args.Exception.Message);
 
-     }
 
-     private void HandlerOnUnhandledExceptionFilterNotRequestCatchPushFrame(object sender,
 
-         DispatcherUnhandledExceptionFilterEventArgs args)
 
-     {
 
-         HandlerOnUnhandledExceptionFilterNotRequestCatch(sender, args);
 
-         var frame = new DispatcherFrame();
 
-         args.Dispatcher.InvokeAsync(() => frame.Continue = false, DispatcherPriority.Background);
 
-         args.Dispatcher.PushFrame(frame);
 
-     }
 
-     private void HandlerOnUnhandledExceptionFilterNotRequestCatch(object sender,
 
-         DispatcherUnhandledExceptionFilterEventArgs args)
 
-     {
 
-         args.RequestCatch = false;
 
-         _numberOfHandlerOnUnhandledEventFilterInvoked += 1;
 
-         Assert.Equal(ExpectedExceptionText, args.Exception.Message);
 
-     }
 
-     private void HandlerOnUnhandledExceptionHandledPushFrame(object sender, DispatcherUnhandledExceptionEventArgs args)
 
-     {
 
-         Assert.Equal(ExpectedExceptionText, args.Exception.Message);
 
-         Assert.False(_numberOfHandlerOnUnhandledEventFilterInvoked == 0,
 
-             "UnhandledExceptionFilter should be invoked before UnhandledException.");
 
-         args.Handled = true;
 
-         _numberOfHandlerOnUnhandledEventInvoked += 1;
 
-         var dispatcher = args.Dispatcher;
 
-         var frame = new DispatcherFrame();
 
-         dispatcher.BeginInvokeShutdown(DispatcherPriority.Background);
 
-         dispatcher.PushFrame(frame);
 
-     }
 
-     private void HandlerOnUnhandledExceptionHandled(object sender, DispatcherUnhandledExceptionEventArgs args)
 
-     {
 
-         Assert.Equal(ExpectedExceptionText, args.Exception.Message);
 
-         Assert.False(_numberOfHandlerOnUnhandledEventFilterInvoked == 0,
 
-             "UnhandledExceptionFilter should be invoked before UnhandledException.");
 
-         args.Handled = true;
 
-         _numberOfHandlerOnUnhandledEventInvoked += 1;
 
-     }
 
-     private void HandlerOnUnhandledExceptionNotHandled(object sender, DispatcherUnhandledExceptionEventArgs args)
 
-     {
 
-         Assert.Equal(ExpectedExceptionText, args.Exception.Message);
 
-         Assert.False(_numberOfHandlerOnUnhandledEventFilterInvoked == 0,
 
-             "UnhandledExceptionFilter should be invoked before UnhandledException.");
 
-         args.Handled = false;
 
-         _numberOfHandlerOnUnhandledEventInvoked += 1;
 
-     }
 
-     private void ThrowAnException()
 
-     {
 
-         throw new Exception(ExpectedExceptionText);
 
-     }
 
- }
 
 
  |