// -------------------------------------------------------------------------------------------------------------------- // // This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. // // // Enables easy marshalling of code to the UI thread. // Borrowed from Caliburn Micro. // // -------------------------------------------------------------------------------------------------------------------- namespace HandBrakeWPF.Utilities { using System; using System.ComponentModel; using System.Diagnostics; using System.Threading.Tasks; using System.Windows; using System.Windows.Threading; /// /// Enables easy marshalling of code to the UI thread. /// public static class Execute { private static System.Action executor = (System.Action)(action => action()); private static Dispatcher dispatcher; private static bool? inDesignMode; /// /// Gets a value indicating whether or not the framework is in design-time mode. /// public static bool InDesignMode { get { if (!Execute.inDesignMode.HasValue) { Execute.inDesignMode = new bool?((bool)DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof(FrameworkElement)).Metadata.DefaultValue); if (!Execute.inDesignMode.GetValueOrDefault(false) && Process.GetCurrentProcess().ProcessName.StartsWith("devenv", StringComparison.Ordinal)) Execute.inDesignMode = new bool?(true); } return Execute.inDesignMode.GetValueOrDefault(false); } } /// /// Initializes the framework using the current dispatcher. /// public static void InitializeWithDispatcher() { Execute.dispatcher = Dispatcher.CurrentDispatcher; Execute.executor = (System.Action)null; } /// /// Resets the executor to use a non-dispatcher-based action executor. /// public static void ResetWithoutDispatcher() { executor = (System.Action)(action => action()); dispatcher = (Dispatcher)null; } /// /// Sets a custom UI thread marshaller. /// /// The marshaller. [Obsolete] public static void SetUIThreadMarshaller(System.Action marshaller) { Execute.executor = marshaller; Execute.dispatcher = (Dispatcher)null; } /// /// The validate dispatcher. /// /// /// Not initialized with dispatcher. /// private static void ValidateDispatcher() { if (Execute.dispatcher == null) throw new InvalidOperationException("Not initialized with dispatcher."); } /// /// Executes the action on the UI thread asynchronously. /// /// The action to execute. public static void BeginOnUIThread(this System.Action action) { Execute.ValidateDispatcher(); Execute.dispatcher.BeginInvoke((Delegate)action); } /// /// Executes the action on the UI thread asynchronously. /// /// /// The action to execute. /// /// /// The . /// public static Task OnUIThreadAsync(this System.Action action) { Execute.ValidateDispatcher(); TaskCompletionSource taskSource = new TaskCompletionSource(); System.Action action1 = (System.Action)(() => { try { action(); taskSource.SetResult((object)null); } catch (Exception ex) { taskSource.SetException(ex); } }); Execute.dispatcher.BeginInvoke((Delegate)action1); return (Task)taskSource.Task; } /// /// The check access. /// /// /// The . /// private static bool CheckAccess() { if (Execute.dispatcher != null) return Execute.dispatcher.CheckAccess(); return true; } /// /// Executes the action on the UI thread. /// /// The action to execute. public static void OnUIThread(this System.Action action) { if (Execute.executor != null) Execute.executor(action); else if (Execute.CheckAccess()) action(); else Execute.OnUIThreadAsync(action).Wait(); } } }