Files
sqltoolsservice/src/Microsoft.SqlTools.Hosting/Utility/AsyncContext.cs
Karl Burtram f00136cffb Fix namespaces for code moved to separate class libraries (#263)
* Create ServiceHost a service-specific class

* Renaming hosting namespace

* Rename credentials namespace

* Fix namespaces
2017-03-02 14:41:06 -08:00

53 lines
1.8 KiB
C#

//
// 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.Utility
{
/// <summary>
/// Simplifies the setup of a SynchronizationContext for the use
/// of async calls in the current thread.
/// </summary>
public static class AsyncContext
{
/// <summary>
/// Starts a new ThreadSynchronizationContext, attaches it to
/// the thread, and then runs the given async main function.
/// </summary>
/// <param name="asyncMainFunc">
/// The Task-returning Func which represents the "main" function
/// for the thread.
/// </param>
public static void Start(Func<Task> 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();
}
}
}