Making singleton instances threadsafe

This commit is contained in:
Benjamin Russell
2016-07-25 12:15:03 -07:00
parent 31576d0731
commit 46032d3e2e
3 changed files with 16 additions and 36 deletions

View File

@@ -3,6 +3,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
// //
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -16,14 +17,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting
/// <summary> /// <summary>
/// SQL Tools VS Code Language Server request handler /// SQL Tools VS Code Language Server request handler
/// </summary> /// </summary>
public class ServiceHost : ServiceHostBase public sealed class ServiceHost : ServiceHostBase
{ {
#region Singleton Instance Code #region Singleton Instance Code
/// <summary> /// <summary>
/// Singleton instance of the instance /// Singleton instance of the service host for internal storage
/// </summary> /// </summary>
private static ServiceHost instance; private static readonly Lazy<ServiceHost> instance = new Lazy<ServiceHost>(() => new ServiceHost());
/// <summary> /// <summary>
/// Creates or retrieves the current instance of the ServiceHost /// Creates or retrieves the current instance of the ServiceHost
@@ -31,11 +32,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting
/// <returns>Instance of the service host</returns> /// <returns>Instance of the service host</returns>
public static ServiceHost Create() public static ServiceHost Create()
{ {
if (instance == null) return instance.Value;
{
instance = new ServiceHost();
}
return instance;
} }
/// <summary> /// <summary>

View File

@@ -20,32 +20,23 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
/// <summary> /// <summary>
/// Main class for Language Service functionality /// Main class for Language Service functionality
/// </summary> /// </summary>
public class LanguageService public sealed class LanguageService
{ {
#region Singleton Instance Implementation #region Singleton Instance Implementation
private static LanguageService instance; private static readonly Lazy<LanguageService> instance = new Lazy<LanguageService>(() => new LanguageService());
public static LanguageService Instance public static LanguageService Instance
{ {
get get { return instance.Value; }
{
if (instance == null)
{
instance = new LanguageService();
}
return instance;
}
} }
/// <summary> /// <summary>
/// Default, parameterless contstructor. /// Default, parameterless constructor.
/// TODO: Remove once the SqlToolsContext stuff is sorted out
/// </summary> /// </summary>
private LanguageService() private LanguageService()
{ {
} }
#endregion #endregion

View File

@@ -15,23 +15,16 @@ using System.Linq;
namespace Microsoft.SqlTools.ServiceLayer.WorkspaceServices namespace Microsoft.SqlTools.ServiceLayer.WorkspaceServices
{ {
public class WorkspaceService<TConfig> where TConfig : new() public class WorkspaceService<TConfig> where TConfig : class, new()
{ {
#region Singleton Instance Implementation #region Singleton Instance Implementation
private static WorkspaceService<TConfig> instance; private static readonly Lazy<WorkspaceService<TConfig>> instance = new Lazy<WorkspaceService<TConfig>>(() => new WorkspaceService<TConfig>());
public static WorkspaceService<TConfig> Instance public static WorkspaceService<TConfig> Instance
{ {
get get { return instance.Value; }
{
if (instance == null)
{
instance = new WorkspaceService<TConfig>();
}
return instance;
}
} }
private WorkspaceService() private WorkspaceService()
@@ -52,9 +45,8 @@ namespace Microsoft.SqlTools.ServiceLayer.WorkspaceServices
public delegate Task DidChangeTextDocumentNotificationTask(ScriptFile[] changedFiles, EventContext eventContext); public delegate Task DidChangeTextDocumentNotificationTask(ScriptFile[] changedFiles, EventContext eventContext);
public List<DidChangeConfigurationNotificationHandler> ConfigurationNotificationHandlers; private List<DidChangeConfigurationNotificationHandler> ConfigurationNotificationHandlers { get; set; }
public List<DidChangeTextDocumentNotificationTask> TextDocumentChangeHandlers; private List<DidChangeTextDocumentNotificationTask> TextDocumentChangeHandlers { get; set; }
#endregion #endregion
@@ -153,7 +145,7 @@ namespace Microsoft.SqlTools.ServiceLayer.WorkspaceServices
Logger.Write(LogLevel.Verbose, msg.ToString()); Logger.Write(LogLevel.Verbose, msg.ToString());
var handlers = TextDocumentChangeHandlers.Select(t => t(changedFiles.ToArray(), eventContext)).ToArray(); var handlers = TextDocumentChangeHandlers.Select(t => t(changedFiles.ToArray(), eventContext));
return Task.WhenAll(handlers); return Task.WhenAll(handlers);
} }
@@ -186,7 +178,7 @@ namespace Microsoft.SqlTools.ServiceLayer.WorkspaceServices
// Propagate the changes to the event handlers // Propagate the changes to the event handlers
var configUpdateTasks = ConfigurationNotificationHandlers.Select( var configUpdateTasks = ConfigurationNotificationHandlers.Select(
t => t(configChangeParams.Settings, CurrentSettings, eventContext)).ToArray(); t => t(configChangeParams.Settings, CurrentSettings, eventContext));
await Task.WhenAll(configUpdateTasks); await Task.WhenAll(configUpdateTasks);
} }