private void InvokeImpl() { SynchronizationContext oldSynchronizationContext = SynchronizationContext.Current; try { // We are executing under the "foreign" execution context, but the // SynchronizationContext must be for the correct dispatcher and // priority. DispatcherSynchronizationContext newSynchronizationContext; if (BaseCompatibilityPreferences.GetReuseDispatcherSynchronizationContextInstance()) { newSynchronizationContext = Dispatcher._defaultDispatcherSynchronizationContext; } else { if (BaseCompatibilityPreferences.GetFlowDispatcherSynchronizationContextPriority()) { newSynchronizationContext = new DispatcherSynchronizationContext(_dispatcher, _priority); } else { newSynchronizationContext = new DispatcherSynchronizationContext(_dispatcher, DispatcherPriority.Normal); } } SynchronizationContext.SetSynchronizationContext(newSynchronizationContext); // Win32 considers timers to be low priority. Avalon does not, since different timers // are associated with different priorities. So we promote the timers before we // invoke any work items. _dispatcher.PromoteTimers(Environment.TickCount); if (_useAsyncSemantics) { try { _result = InvokeDelegateCore(); } catch (Exception e) { // Remember this for the later call to InvokeCompletions. _exception = e; } } else { // Invoke the delegate and route exceptions through the dispatcher events. _result = _dispatcher.WrappedInvoke(_method, _args, _numArgs, null); // Note: we do not catch exceptions, they flow out the the Dispatcher.UnhandledException handling. } } finally { SynchronizationContext.SetSynchronizationContext(oldSynchronizationContext); } }
/// <summary> /// Synchronously invoke the callback in the SynchronizationContext. /// </summary> public override void Send(SendOrPostCallback d, Object state) { // Call the Invoke overload that preserves the behavior of passing // exceptions to Dispatcher.UnhandledException. if (BaseCompatibilityPreferences.GetInlineDispatcherSynchronizationContextSend() && _dispatcher.CheckAccess()) { // Same-thread, use send priority to avoid any reentrancy. _dispatcher.Invoke(DispatcherPriority.Send, d, state); } else { // Cross-thread, use the cached priority. _dispatcher.Invoke(_priority, d, state); } }
/// <summary> /// Create a copy of this SynchronizationContext. /// </summary> public override SynchronizationContext CreateCopy() { DispatcherSynchronizationContext copy; if (BaseCompatibilityPreferences.GetReuseDispatcherSynchronizationContextInstance()) { copy = this; } else { if (BaseCompatibilityPreferences.GetFlowDispatcherSynchronizationContextPriority()) { copy = new DispatcherSynchronizationContext(_dispatcher, _priority); } else { copy = new DispatcherSynchronizationContext(_dispatcher, DispatcherPriority.Normal); } } return(copy); }