// // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; using System.Threading; using System.Threading.Tasks; namespace Microsoft.SqlTools.EditorServices.Utility { /// /// Simplifies the setup of a SynchronizationContext for the use /// of async calls in the current thread. /// public static class AsyncContext { /// /// Starts a new ThreadSynchronizationContext, attaches it to /// the thread, and then runs the given async main function. /// /// /// The Task-returning Func which represents the "main" function /// for the thread. /// public static void Start(Func asyncMainFunc) { // Is there already a synchronization context? if (SynchronizationContext.Current != null) { throw new InvalidOperationException( "A SynchronizationContext is already assigned on this thread."); } // Create and register a synchronization context for this thread var threadSyncContext = new ThreadSynchronizationContext(); SynchronizationContext.SetSynchronizationContext(threadSyncContext); // Get the main task and act on its completion Task asyncMainTask = asyncMainFunc(); asyncMainTask.ContinueWith( t => threadSyncContext.EndLoop(), TaskScheduler.Default); // Start the synchronization context's request loop and // wait for the main task to complete threadSyncContext.RunLoopOnCurrentThread(); asyncMainTask.GetAwaiter().GetResult(); } } }