我有一个类HashSet<T>
,它不是线程安全的,我想通过使用lock
语句来保证线程安全。
public sealed class DatabaseContextResolver
{
#region Constructors
DatabaseContextResolver()
{
_registeredContexts = new Hashtable();
}
#endregion
#region Properties
static readonly object ReadWriterLock = new object();
static readonly Lazy<DatabaseContextResolver> DatabaseContextResolverInstantiator = new Lazy<DatabaseContextResolver>(() => new DatabaseContextResolver());
internal static DatabaseContextResolver Instance => DatabaseContextResolverInstantiator.Value;
readonly Hashtable _registeredContexts;
#endregion
#region Methods
public void RegisterContext<TContext>(TContext context, string contextName)
where TContext : class
{
context.ThrowIfNull(new MongoMigrationContextException("The context to register should not be null."));
var namedContextTypeDependency = new NamedTypeDependency(contextName, typeof(TContext), context);
if (_registeredContexts.ContainsKey(namedContextTypeDependency.ToString()))
{ throw new MongoMigrationDependencyException("The context cannot be registered because it's already registered."); }
lock (ReadWriterLock)
{
if (!_registeredContexts.ContainsKey(namedContextTypeDependency.ToString()))
{ _registeredContexts.Add(namedContextTypeDependency.ToString(), namedContextTypeDependency); }
else
{ throw new MongoMigrationDependencyException("The context cannot be registered because it's already registered."); }
}
}
internal void Clear()
{
_registeredContexts.Clear();
}
#endregion
}
使用Lazy<T>
使此类成为线程安全的,因此我确信在给定时间只存在一个实例。这个假设是否正确?
我有一个clear()
方法可以清除HashSet<T>
中的项目。
现在,我确实有几个xUnit测试,它们会向这个类添加项目。
这是通过以下代码完成的:
DatabaseContextResolver.Instance.RegisterContext(this, contextName);
当我在xUnit中运行所有测试时,它们中的某些测试失败了,因为HashSet<T>
中具有相同键的项目已经存在?
我认为我的实现是线程安全的吗?
每个xUnit类(包含影响此问题的多个测试)都会实现IDisposable
并调用clear()
方法。