using System; using ICD.Common.Properties; using ICD.Common.Utils.Services; using ICD.Common.Utils.Services.Logging; #if SIMPLSHARP using Crestron.SimplSharp; #else using System.Threading.Tasks; #endif namespace ICD.Common.Utils { public static class ThreadingUtils { /// /// Wait until the given condition is true. /// /// /// /// False if the call times out public static bool Wait(Func condition, long timeout) { if (condition == null) throw new ArgumentNullException("condition"); DateTime end = IcdEnvironment.GetLocalTime().AddMilliseconds(timeout); while (!condition()) { if (IcdEnvironment.GetLocalTime() >= end) return false; } return true; } /// /// Puts the current thread to sleep for the given amount of time. /// /// public static void Sleep(int milliseconds) { #if SIMPLSHARP CrestronEnvironment.Sleep(milliseconds); #else Task.Delay(TimeSpan.FromMilliseconds(milliseconds)).Wait(); #endif } /// /// Executes the callback as a short-lived, threaded task. /// /// [PublicAPI] public static object SafeInvoke(Action callback) { return SafeInvoke(unused => callback(), null); } /// /// Executes the callback as a short-lived, threaded task. /// /// /// /// [PublicAPI] public static object SafeInvoke(Action callback, T param) { #if SIMPLSHARP return CrestronInvoke.BeginInvoke(unused => GetHandledCallback(callback, param)(), null); #else return Task.Run(GetHandledCallback(callback, param)); #endif } /// /// Wraps the given callback in a try/catch to avoid crashing crestron programs. /// http://www.crestronlabs.com/showthread.php?12205-Exception-in-CrestronInvoke-thread-crashes-the-program /// /// /// /// private static Action GetHandledCallback(Action callback, T param) { return () => { try { callback(param); } catch (Exception e) { ServiceProvider.TryGetService() .AddEntry(eSeverity.Error, e, "{0} failed to execute callback", typeof(ThreadingUtils).Name); } }; } } }