diff --git a/src/Microsoft.SqlTools.Hosting/Hosting/Protocol/MessageDispatcher.cs b/src/Microsoft.SqlTools.Hosting/Hosting/Protocol/MessageDispatcher.cs
index d188f22c..fca31dbc 100644
--- a/src/Microsoft.SqlTools.Hosting/Hosting/Protocol/MessageDispatcher.cs
+++ b/src/Microsoft.SqlTools.Hosting/Hosting/Protocol/MessageDispatcher.cs
@@ -57,6 +57,12 @@ namespace Microsoft.SqlTools.Hosting.Protocol
protected MessageWriter MessageWriter { get; private set; }
+ ///
+ /// Whether the message should be handled without blocking the main thread.
+ ///
+ public bool ParallelMessageProcessing { get; set; }
+
+
#endregion
#region Constructors
@@ -305,22 +311,39 @@ namespace Microsoft.SqlTools.Hosting.Protocol
if (handlerToAwait != null)
{
- try
+ if (this.ParallelMessageProcessing)
{
- await handlerToAwait;
- }
- catch (TaskCanceledException)
- {
- // Some tasks may be cancelled due to legitimate
- // timeouts so don't let those exceptions go higher.
- }
- catch (Exception e)
- {
- if (!(e is AggregateException && ((AggregateException)e).InnerExceptions[0] is TaskCanceledException))
+ // Run the task in a separate thread so that the main
+ // thread is not blocked.
+ _ = Task.Run(() =>
{
- // Log the error but don't rethrow it to prevent any errors in the handler from crashing the service
- Logger.Write(TraceEventType.Error, string.Format("An unexpected error occured in the request handler: {0}", e.ToString()));
- }
+ _ = RunTask(handlerToAwait);
+ });
+ }
+ else
+ {
+ await RunTask(handlerToAwait);
+ }
+ }
+ }
+
+ private async Task RunTask(Task task)
+ {
+ try
+ {
+ await task;
+ }
+ catch (TaskCanceledException)
+ {
+ // Some tasks may be cancelled due to legitimate
+ // timeouts so don't let those exceptions go higher.
+ }
+ catch (Exception e)
+ {
+ if (!(e is AggregateException && ((AggregateException)e).InnerExceptions[0] is TaskCanceledException))
+ {
+ // Log the error but don't rethrow it to prevent any errors in the handler from crashing the service
+ Logger.Write(TraceEventType.Error, string.Format("An unexpected error occured in the request handler: {0}", e.ToString()));
}
}
}
diff --git a/src/Microsoft.SqlTools.Hosting/Hosting/Protocol/ProtocolEndpoint.cs b/src/Microsoft.SqlTools.Hosting/Hosting/Protocol/ProtocolEndpoint.cs
index 1dc64521..f043e429 100644
--- a/src/Microsoft.SqlTools.Hosting/Hosting/Protocol/ProtocolEndpoint.cs
+++ b/src/Microsoft.SqlTools.Hosting/Hosting/Protocol/ProtocolEndpoint.cs
@@ -44,7 +44,7 @@ namespace Microsoft.SqlTools.Hosting.Protocol
/// handlers for requests, responses, and events that are
/// transmitted through the channel.
///
- protected MessageDispatcher MessageDispatcher { get; set; }
+ internal MessageDispatcher MessageDispatcher { get; set; }
///
/// Initializes an instance of the protocol server using the
diff --git a/src/Microsoft.SqlTools.Hosting/Utility/CommandOptions.cs b/src/Microsoft.SqlTools.Hosting/Utility/CommandOptions.cs
index e7379edb..a75ddf95 100644
--- a/src/Microsoft.SqlTools.Hosting/Utility/CommandOptions.cs
+++ b/src/Microsoft.SqlTools.Hosting/Utility/CommandOptions.cs
@@ -63,6 +63,9 @@ namespace Microsoft.SqlTools.Hosting.Utility
case "-service-name":
ServiceName = args[++i];
break;
+ case "-parallel-message-processing":
+ ParallelMessageProcessing = true;
+ break;
default:
ErrorMessage += string.Format("Unknown argument \"{0}\"" + Environment.NewLine, argName);
break;
@@ -131,6 +134,12 @@ namespace Microsoft.SqlTools.Hosting.Utility
public bool AutoFlushLog { get; private set; } = false;
+ ///
+ /// A temporary flag to decide whether the message handling should block the main thread.
+ /// Eventually we will fix the issues and make this the default behavior.
+ ///
+ public bool ParallelMessageProcessing { get; private set; } = false;
+
public virtual void SetLocale(string locale)
{
try
@@ -155,7 +164,7 @@ namespace Microsoft.SqlTools.Hosting.Utility
// Creating cultureInfo from our given locale
CultureInfo language = new CultureInfo(locale);
Locale = locale;
-
+
// Allow the system set Number Format and Date Format to be preserved when changing the locale.
NumberFormatInfo NumberFormat = CultureInfo.CurrentCulture.NumberFormat;
DateTimeFormatInfo DateTimeFormat = CultureInfo.CurrentCulture.DateTimeFormat;
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Program.cs b/src/Microsoft.SqlTools.ServiceLayer/Program.cs
index ba9ec101..a5f1e711 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Program.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Program.cs
@@ -45,6 +45,7 @@ namespace Microsoft.SqlTools.ServiceLayer
SqlToolsContext sqlToolsContext = new SqlToolsContext(hostDetails);
ServiceHost serviceHost = HostLoader.CreateAndStartServiceHost(sqlToolsContext);
+ serviceHost.MessageDispatcher.ParallelMessageProcessing = commandOptions.ParallelMessageProcessing;
// If this service was started by another process, then it should shutdown when that parent process does.
if (commandOptions.ParentProcessId != null)
@@ -58,9 +59,9 @@ namespace Microsoft.SqlTools.ServiceLayer
}
catch (Exception ex)
{
- try
+ try
{
- Logger.WriteWithCallstack(TraceEventType.Critical, $"An unhandled exception occurred: {ex}");
+ Logger.WriteWithCallstack(TraceEventType.Critical, $"An unhandled exception occurred: {ex}");
}
catch (Exception loggerEx)
{