using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Threading; using Tango.Logging; namespace Tango.Core.Helpers { /// /// Contains several UI threading helper methods. /// public static class ThreadsHelper { private static Dispatcher _dispatcher; //Holds the current dispatcher. public static event Action DispatcherSet; private static List _whenAvailableActions; private static bool _whenAvailableActionsInvoked; private static bool _hasDispatcher; static ThreadsHelper() { _whenAvailableActions = new List(); } /// /// Sets the current dispatcher. /// /// The dispatcher. public static void SetDisptacher(Dispatcher dispatcher) { _dispatcher = dispatcher; DispatcherSet?.Invoke(dispatcher); _hasDispatcher = true; if (!_whenAvailableActionsInvoked) { foreach (var action in _whenAvailableActions) { InvokeUI(action); } _whenAvailableActionsInvoked = true; } } /// /// Invokes the UI thread. /// /// The action. public static void InvokeUI(Action action) { if (_dispatcher == null) { LogManager.Default.Log(new NullReferenceException("The UI dispatcher was not set!")); action(); } else { _dispatcher.BeginInvoke(action); } } /// /// Invokes the UI thread while blocking the current thread. /// /// The action. public static void InvokeUINow(Action action) { if (_dispatcher == null) { LogManager.Default.Log(new NullReferenceException("The UI dispatcher was not set!")); action(); } else { _dispatcher.Invoke(action); } } /// /// Invokes UI thread after a dispatcher has been set by . /// /// The action. public static void InvokeWhenAvailable(Action action) { if (_hasDispatcher) { InvokeUI(action); } else { _whenAvailableActions.Add(action); } } /// /// Starts a new STA thread which will be running the specified action. /// /// The action. public static void StartStaThread(Action action) { Thread thread = new Thread(() => { action(); }); thread.SetApartmentState(ApartmentState.STA); thread.IsBackground = true; thread.Start(); } } }