using System; using System.Threading; using System.Threading.Tasks; using System.Collections.Concurrent; using System.Collections.Generic; namespace RealtimeApp { /// /// Mimics UI thread under .Net console. /// public class SingleThreadSynchronizationContext : SynchronizationContext { private readonly BlockingCollection> queue = new BlockingCollection>(); public override void Post(SendOrPostCallback d, object state) { queue.Add(new KeyValuePair(d, state)); } public void RunOnCurrentThread() { while (queue.TryTake(out KeyValuePair workItem, Timeout.Infinite)) { workItem.Key(workItem.Value); } } public void Complete() { queue.CompleteAdding(); } public static void Run(Func func) { SynchronizationContext prevContext = Current; try { SingleThreadSynchronizationContext syncContext = new SingleThreadSynchronizationContext(); SetSynchronizationContext(syncContext); Task t = func(); syncContext.RunOnCurrentThread(); t.GetAwaiter().GetResult(); } finally { SetSynchronizationContext(prevContext); } } } }