using System; using System.Threading; using System.Threading.Tasks; namespace ElectronNET.API { internal static class AsyncHelper { private static readonly TaskFactory _taskFactory = new TaskFactory(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default); public static TResult RunSync(Func> func) => _taskFactory .StartNew(func) .Unwrap() .GetAwaiter() .GetResult(); public static void RunSync(Func func) => _taskFactory .StartNew(func) .Unwrap() .GetAwaiter() .GetResult(); public static async Task TimeoutAfter(this Task task, TimeSpan timeout) { using (var timeoutCancellationTokenSource = new CancellationTokenSource()) { var completedTask = await Task.WhenAny(task, Task.Delay(timeout, timeoutCancellationTokenSource.Token)); if (completedTask == task) { timeoutCancellationTokenSource.Cancel(); return await task; // Very important in order to propagate exceptions } else { throw new TimeoutException($"{nameof(TimeoutAfter)}: The operation has timed out after {timeout:mm\\:ss}"); } } } } }