public async Task Test_async_void_exceptions_are_captured() { await using var apartment = new WinFormsApartment(); await apartment.Run(async() => { await Task.Yield(); Assert.IsTrue(SynchronizationContext.Current is System.Windows.Forms.WindowsFormsSynchronizationContext); async void AsyncVoidMethod1() { await Task.Delay(200); throw new InvalidOperationException(); } async void AsyncVoidMethod2() { await Task.Delay(400); throw new NotSupportedException(); } AsyncVoidMethod1(); AsyncVoidMethod2(); }); // we can't track background operations with WindowsFormsSynchronizationContext Assert.IsTrue(apartment.AnyBackgroundOperation == null); await Task.Delay(600); // race with both async void methods apartment.Complete(); try { await apartment.Completion.WithAggregatedExceptions(); Assert.Fail("Must not reach here, expecting exceptions."); } catch (AssertFailedException) { throw; } catch (Exception ex) { apartment.ClearExceptions(); // we expect to see 2 exceptions wrapped as AggregateException var aggregate = ex as AggregateException; Assert.IsNotNull(aggregate); Assert.IsTrue(aggregate !.InnerExceptions.Count == 2); Assert.IsTrue(aggregate.InnerExceptions[0] is InvalidOperationException); Assert.IsTrue(aggregate.InnerExceptions[1] is NotSupportedException); } }
public async Task Test_TimerYield_in_WinFormsApartment() { await using var apartment = new WinFormsApartment(); var sw = new Stopwatch(); await apartment.Run(async() => { Assert.IsTrue(SynchronizationContext.Current is WindowsFormsSynchronizationContext); sw.Start(); await InputHelpers.TimerYield(1000); sw.Stop(); }); var lapse = sw.ElapsedMilliseconds; Assert.IsTrue(lapse > 900 && lapse < 1100); }