Hir*_*aka 8 .net c# thread-safety
在 C# 中处理延迟初始化对象的线程安全方法是什么?假设我有以下Lazy
构造:
Lazy<MyClass> lazy = new Lazy<MyClass>(() => MyClass.Create(), true);
Run Code Online (Sandbox Code Playgroud)
稍后,我可能想处置MyClass
创建的实例。大多数现有的解决方案都推荐这样的内容:
if (lazy.IsValueCreated)
{
lazy.Value.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
但据我所知,IsValueCreated
没有任何锁:https://referencesource.microsoft.com/#mscorlib/system/Lazy.cs,284
MyClass
这意味着当我们检查 时,另一个线程可能正在初始化过程中IsValueCreated
。在这种情况下,我们将观察IsValueCreated
到错误,并最终泄漏资源。这里正确的做法是什么?还是我错过了一些微妙的细节?
我会将我的惰性实例设置为 null ,Dispose()
以便任何进一步的访问都会失败(例如 throwing ObjectDisposedException
)。然后创建一个 getter 来处理这个问题:
MyClass MyObj => lazy?.Value ?? throw new ObjectDisposedException(nameof(MyObj));
public void Dispose()
{
var lazyBeforeDispose = Interlocked.Exchange(ref lazy, null);
if (lazyBeforeDispose?.IsValueCreated ?? false)
{
lazyBeforeDispose.Value.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4348 次 |
最近记录: |