From 5c1b45b2ecc91c9420ced9087cc193bcc5081482 Mon Sep 17 00:00:00 2001 From: Johan Laanstra Date: Fri, 14 Jan 2022 14:58:22 -0800 Subject: [PATCH 1/2] Support DispatcherQueueSynchronizationContext.Send. --- ...g.DispatcherQueueSynchronizationContext.cs | 87 +++++++++++-------- 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs b/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs index f1f5a7e5c..b5094c15c 100644 --- a/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs +++ b/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs @@ -1,38 +1,51 @@ -using System; -using System.Threading; -using Microsoft.System; - -namespace Microsoft.System -{ - /// - /// DispatcherQueueSyncContext allows developers to await calls and get back onto the - /// UI thread. Needs to be installed on the UI thread through DispatcherQueueSyncContext.SetForCurrentThread - /// - public class DispatcherQueueSynchronizationContext : SynchronizationContext - { - private readonly DispatcherQueue m_dispatcherQueue; - - public DispatcherQueueSynchronizationContext(DispatcherQueue dispatcherQueue) - { - m_dispatcherQueue = dispatcherQueue; - } - - public override void Post(SendOrPostCallback d, object state) - { - if (d == null) - throw new ArgumentNullException(nameof(d)); - - m_dispatcherQueue.TryEnqueue(() => d(state)); - } - - public override void Send(SendOrPostCallback d, object state) - { - throw new NotSupportedException("Send not supported"); - } - - public override SynchronizationContext CreateCopy() - { - return new DispatcherQueueSynchronizationContext(m_dispatcherQueue); - } - } +using System; +using System.Threading; +using Microsoft.System; + +namespace Microsoft.System +{ + /// + /// DispatcherQueueSyncContext allows developers to await calls and get back onto the + /// UI thread. Needs to be installed on the UI thread through DispatcherQueueSyncContext.SetForCurrentThread + /// + public class DispatcherQueueSynchronizationContext : SynchronizationContext + { + private readonly DispatcherQueue m_dispatcherQueue; + + public DispatcherQueueSynchronizationContext(DispatcherQueue dispatcherQueue) + { + m_dispatcherQueue = dispatcherQueue; + } + + public override void Post(SendOrPostCallback d, object state) + { + if (d == null) + throw new ArgumentNullException(nameof(d)); + + m_dispatcherQueue.TryEnqueue(() => d(state)); + } + + public override void Send(SendOrPostCallback d, object state) + { + if (m_dispatcherQueue.HasThreadAccess) + { + d(state); + } + else + { + var m = new ManualResetEvent(false); + m_dispatcherQueue.TryEnqueue(() => + { + d(state); + m.Set(); + }); + m.WaitOne(); + } + } + + public override SynchronizationContext CreateCopy() + { + return new DispatcherQueueSynchronizationContext(m_dispatcherQueue); + } + } } \ No newline at end of file From 7e8bc5c334d5b1782d9b200211e98ca2b179c7e6 Mon Sep 17 00:00:00 2001 From: Johan Laanstra Date: Fri, 14 Jan 2022 15:40:42 -0800 Subject: [PATCH 2/2] Ensure exceptions flwo back correctly. --- ...g.DispatcherQueueSynchronizationContext.cs | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs b/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs index b5094c15c..301da6b9e 100644 --- a/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs +++ b/src/Projections/Reunion/Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.ExceptionServices; using System.Threading; using Microsoft.System; @@ -34,12 +35,28 @@ public override void Send(SendOrPostCallback d, object state) else { var m = new ManualResetEvent(false); + ExceptionDispatchInfo edi = null; + m_dispatcherQueue.TryEnqueue(() => { - d(state); - m.Set(); + try + { + d(state); + } + catch (Exception ex) + { + edi = ExceptionDispatchInfo.Capture(ex); + } + finally + { + m.Set(); + } }); m.WaitOne(); + +#pragma warning disable CA1508 // Avoid dead conditional code + edi?.Throw(); +#pragma warning restore CA1508 // Avoid dead conditional code } }