/// <summary> /// Executes an async Func<T> synchronously and returns the result /// - use when you really cannot use async/await /// - NEVER use Task.Wait() or Task.Result if the underlying code uses async/await /// </summary> /// <typeparam name="T">Return Type</typeparam> /// <param name="task">Task<T> method to execute</param> /// <returns></returns> public static T RunSync <T>(Func <Task <T> > task) { var oldContext = SynchronizationContext.Current; var context = new ExclusiveSynchronizationContext(); SynchronizationContext.SetSynchronizationContext(context); var ret = default(T); context.Post(async _ => { try { ret = await task(); } catch (Exception e) { context.InnerException = e; throw; } finally { context.EndMessageLoop(); } }, null); context.BeginMessageLoop(); SynchronizationContext.SetSynchronizationContext(oldContext); return(ret); }
/// <summary> /// Executes an async Action synchronously /// - use when you really cannot use async/await /// - NEVER use Task.Wait() or Task.Result if the underlying code uses async/await /// </summary> /// <param name="task">Action to execute</param> public static void RunSync(Func <Task> task) { var oldContext = SynchronizationContext.Current; var context = new ExclusiveSynchronizationContext(); SynchronizationContext.SetSynchronizationContext(context); context.Post(async _ => { try { await task(); } catch (Exception e) { context.InnerException = e; throw; } finally { context.EndMessageLoop(); } }, null); context.BeginMessageLoop(); SynchronizationContext.SetSynchronizationContext(oldContext); }