// // 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.Collections.Concurrent; using System.Threading; namespace Microsoft.SqlTools.ServiceLayer.Utility { /// /// Provides a SynchronizationContext implementation that can be used /// in console applications or any thread which doesn't have its /// own SynchronizationContext. /// public class ThreadSynchronizationContext : SynchronizationContext { #region Private Fields private BlockingCollection> requestQueue = new BlockingCollection>(); #endregion #region Constructors /// /// Posts a request for execution to the SynchronizationContext. /// This will be executed on the SynchronizationContext's thread. /// /// /// The callback to be invoked on the SynchronizationContext's thread. /// /// /// A state object to pass along to the callback when executed through /// the SynchronizationContext. /// public override void Post(SendOrPostCallback callback, object state) { // Add the request to the queue this.requestQueue.Add( new Tuple( callback, state)); } #endregion #region Public Methods /// /// Starts the SynchronizationContext message loop on the current thread. /// public void RunLoopOnCurrentThread() { Tuple request; while (this.requestQueue.TryTake(out request, Timeout.Infinite)) { // Invoke the request's callback request.Item1(request.Item2); } } /// /// Ends the SynchronizationContext message loop. /// public void EndLoop() { // Tell the blocking queue that we're done this.requestQueue.CompleteAdding(); } #endregion } }