diff --git a/src/Microsoft.SqlTools.ServiceLayer/Admin/Common/DataContainer.cs b/src/Microsoft.SqlTools.ServiceLayer/Admin/Common/DataContainer.cs index 7528e79f..f7a7e2ce 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Admin/Common/DataContainer.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Admin/Common/DataContainer.cs @@ -1119,27 +1119,30 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin throw new ArgumentException("sourceXml"); } - MemoryStream memoryStream = new MemoryStream(); - StreamWriter streamWriter = new StreamWriter(memoryStream); + using (MemoryStream memoryStream = new MemoryStream()) + { + using (StreamWriter streamWriter = new StreamWriter(memoryStream)) + { + // Writes the xml to the memory stream + streamWriter.Write(sourceXml); + streamWriter.Flush(); - // Writes the xml to the memory stream - streamWriter.Write(sourceXml); - streamWriter.Flush(); + // Resets the stream to the beginning + memoryStream.Seek(0, SeekOrigin.Begin); - // Resets the stream to the beginning - memoryStream.Seek(0, SeekOrigin.Begin); + // Creates the XML reader from the stream + // and moves it to the correct node + XmlReader xmlReader = XmlReader.Create(memoryStream); + xmlReader.MoveToContent(); - // Creates the XML reader from the stream - // and moves it to the correct node - XmlReader xmlReader = XmlReader.Create(memoryStream); - xmlReader.MoveToContent(); + // generate the xml document + XmlDocument xmlDocument = new XmlDocument(); + xmlDocument.PreserveWhitespace = true; + xmlDocument.LoadXml(xmlReader.ReadOuterXml()); - // generate the xml document - XmlDocument xmlDocument = new XmlDocument(); - xmlDocument.PreserveWhitespace = true; - xmlDocument.LoadXml(xmlReader.ReadOuterXml()); - - return xmlDocument; + return xmlDocument; + } + } } #endregion diff --git a/src/Microsoft.SqlTools.ServiceLayer/Admin/Database/DatabasePrototype.cs b/src/Microsoft.SqlTools.ServiceLayer/Admin/Database/DatabasePrototype.cs index c7e2bfc4..39b582a3 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Admin/Database/DatabasePrototype.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Admin/Database/DatabasePrototype.cs @@ -647,17 +647,20 @@ WHERE do.database_id = @DbID { //If it's under v12 we need to query the master DB directly since that has the views containing the necessary information using (var conn = new SqlConnection(context.Server.ConnectionContext.ConnectionString)) { - var cmd = new SqlCommand(dbSloQuery, conn); - cmd.Parameters.AddWithValue("@DbID", db.ID); - conn.Open(); - SqlDataReader reader = cmd.ExecuteReader(); - while (reader.Read()) + using (var cmd = new SqlCommand(dbSloQuery, conn)) { - this.configuredServiceLevelObjective = reader["configured_slo_name"].ToString(); - this.currentServiceLevelObjective = reader["current_slo_name"].ToString(); - break; //Got our service level objective so we're done + cmd.Parameters.AddWithValue("@DbID", db.ID); + conn.Open(); + using (SqlDataReader reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + this.configuredServiceLevelObjective = reader["configured_slo_name"].ToString(); + this.currentServiceLevelObjective = reader["current_slo_name"].ToString(); + break; //Got our service level objective so we're done + } + } } - } } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Admin/Database/DatabasePrototypeAzure.cs b/src/Microsoft.SqlTools.ServiceLayer/Admin/Database/DatabasePrototypeAzure.cs index b8b3df3e..f7b2a83e 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Admin/Database/DatabasePrototypeAzure.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Admin/Database/DatabasePrototypeAzure.cs @@ -177,33 +177,35 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin //Altering the DB needs to be done on the master DB using (var conn = new SqlConnection(this.context.ServerConnection.GetDatabaseConnection("master").ConnectionString)) - { - var cmd = new SqlCommand(); - cmd.Connection = conn; - conn.Open(); + { + using (var cmd = new SqlCommand()) + { + cmd.Connection = conn; + conn.Open(); - //Only run the alter statements for modifications made. This is mostly to allow the non-Azure specific - //properties to be updated when a SLO change is in progress, but it also is beneficial to save trips to the - //server whenever we can (especially when Azure is concerned) - if (currentState.azureEdition != originalState.azureEdition || - currentState.currentServiceLevelObjective != originalState.currentServiceLevelObjective || - currentState.maxSize != originalState.maxSize) - { - cmd.CommandText = alterDbPropertiesStatement; - cmd.ExecuteNonQuery(); - } + //Only run the alter statements for modifications made. This is mostly to allow the non-Azure specific + //properties to be updated when a SLO change is in progress, but it also is beneficial to save trips to the + //server whenever we can (especially when Azure is concerned) + if (currentState.azureEdition != originalState.azureEdition || + currentState.currentServiceLevelObjective != originalState.currentServiceLevelObjective || + currentState.maxSize != originalState.maxSize) + { + cmd.CommandText = alterDbPropertiesStatement; + cmd.ExecuteNonQuery(); + } - if (currentState.recursiveTriggers != originalState.recursiveTriggers) - { - cmd.CommandText = alterAzureDbRecursiveTriggersEnabledStatement; - cmd.ExecuteNonQuery(); - } + if (currentState.recursiveTriggers != originalState.recursiveTriggers) + { + cmd.CommandText = alterAzureDbRecursiveTriggersEnabledStatement; + cmd.ExecuteNonQuery(); + } - if (currentState.isReadOnly != originalState.isReadOnly) - { - cmd.CommandText = alterAzureDbIsReadOnlyStatement; - cmd.ExecuteNonQuery(); - } + if (currentState.isReadOnly != originalState.isReadOnly) + { + cmd.CommandText = alterAzureDbIsReadOnlyStatement; + cmd.ExecuteNonQuery(); + } + } } //Because we didn't use SMO to do the alter we should refresh the DB object so it picks up the correct properties diff --git a/src/Microsoft.SqlTools.ServiceLayer/HostLoader.cs b/src/Microsoft.SqlTools.ServiceLayer/HostLoader.cs index 49325883..44b71b9a 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/HostLoader.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/HostLoader.cs @@ -2,6 +2,7 @@ // 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 Microsoft.SqlTools.Credentials; using Microsoft.SqlTools.Extensibility; using Microsoft.SqlTools.Hosting; @@ -13,7 +14,6 @@ using Microsoft.SqlTools.ServiceLayer.EditData; using Microsoft.SqlTools.ServiceLayer.Hosting; using Microsoft.SqlTools.ServiceLayer.LanguageServices; using Microsoft.SqlTools.ServiceLayer.Metadata; -using Microsoft.SqlTools.ServiceLayer.ObjectExplorer; using Microsoft.SqlTools.ServiceLayer.QueryExecution; using Microsoft.SqlTools.ServiceLayer.Scripting; using Microsoft.SqlTools.ServiceLayer.SqlContext; diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/BindingQueue.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/BindingQueue.cs index cb326bbc..91d71944 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/BindingQueue.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/BindingQueue.cs @@ -14,7 +14,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices /// /// Main class for the Binding Queue /// - public class BindingQueue where T : IBindingContext, new() + public class BindingQueue : IDisposable where T : IBindingContext, new() { private CancellationTokenSource processQueueCancelToken = new CancellationTokenSource(); @@ -313,5 +313,24 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices } } } + + public void Dispose() + { + if (itemQueuedEvent != null) + { + itemQueuedEvent.Dispose(); + } + + if (this.BindingContextMap != null) + { + foreach (var item in this.BindingContextMap) + { + if (item.Value != null && item.Value.ServerConnection != null && item.Value.ServerConnection.SqlConnectionObject != null) + { + item.Value.ServerConnection.SqlConnectionObject.Close(); + } + } + } + } } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs index ed52e61b..c5097fe7 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs @@ -36,7 +36,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices /// Main class for Language Service functionality including anything that requires knowledge of /// the language to perform, such as definitions, intellisense, etc. /// - public sealed class LanguageService + public sealed class LanguageService: IDisposable { #region Singleton Instance Implementation @@ -249,6 +249,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices { Logger.Write(LogLevel.Verbose, "Shutting down language service"); DeletePeekDefinitionScripts(); + this.Dispose(); await Task.FromResult(0); }); @@ -1716,5 +1717,13 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices return string.Empty; } + + public void Dispose() + { + if (bindingQueue != null) + { + bindingQueue.Dispose(); + } + } } } \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/TaskServices/SqlTask.cs b/src/Microsoft.SqlTools.ServiceLayer/TaskServices/SqlTask.cs index 0e654b6e..324cd734 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/TaskServices/SqlTask.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/TaskServices/SqlTask.cs @@ -148,28 +148,29 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices try { - if (TaskToCancel != null) + using (AutoResetEvent onCompletedEvent = new AutoResetEvent(initialState: false)) { - AutoResetEvent onCompletedEvent = new AutoResetEvent(initialState: false); - Task cancelTask = Task.Run(() => CancelTaskAsync(TokenSource.Token, onCompletedEvent)); - - completedTask = await Task.WhenAny(performTask, cancelTask); - - // Release the cancelTask - if (completedTask == performTask) + if (TaskToCancel != null) { - onCompletedEvent.Set(); + Task cancelTask = Task.Run(() => CancelTaskAsync(TokenSource.Token, onCompletedEvent)); + + completedTask = await Task.WhenAny(performTask, cancelTask); + + // Release the cancelTask + if (completedTask == performTask) + { + onCompletedEvent.Set(); + } + } + else + { + completedTask = await Task.WhenAny(performTask); } - } - else - { - completedTask = await Task.WhenAny(performTask); - } - - AddMessage(completedTask.Result.TaskStatus == SqlTaskStatus.Failed ? completedTask.Result.ErrorMessage : SR.TaskCompleted, - completedTask.Result.TaskStatus); - taskResult = completedTask.Result; + AddMessage(completedTask.Result.TaskStatus == SqlTaskStatus.Failed ? completedTask.Result.ErrorMessage : SR.TaskCompleted, + completedTask.Result.TaskStatus); + taskResult = completedTask.Result; + } } catch (OperationCanceledException) {