WeakReference<T> 的文档具有线程安全的通用样板:
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
但是,我想知道无论如何使用 WeakReference
特别是,我想知道允许并发访问这样的东西是否安全:
class MyRef<T> where T : class
{
private readonly Func<Task<T>> _fetcher;
private readonly WeakReference<T> _wref;
public MyRef(Func<Task<T>> fetcher, T target = null)
{
_fetcher = fetcher;
_wref = new WeakReference<T>(target);
}
public async Task<T> GetTargetAsync()
{
T target;
if (!_wref.TryGetTarget(out target))
{
target = await _fetcher();
_wref.SetTarget(target);
}
return target;
}
}
两者都是TryGetTarget
和 SetTarget
在这里使用,可能被多个线程同时调用。
它们都在调用本地代码实现的私有(private)外部 Target
属性。 ( Reference source )
在我开始使用同步锁保护上述代码之前,我想知道 native 实现是否真的对并发访问不安全。
什么对我来说是安全?
简单地说,如果我可以使用上面的代码而不会由于同时调用这两个方法而导致任何意外异常或访问冲突。
更明确地说:
TryGetTarget
会返回true
并给我一个非空引用;或false
。没有异常(exception)。SetTarget
不会导致任何异常。
最佳答案
通过查看 ecallist.h我们可以看到 WeakTarget
的内部方法/WeakTarget<T>
在 WeakReferenceNative
中实现/WeakReferenceOfTNative
类。看着他们的source code我们可以看到有一个 AcquireWeakHandleSpinLock
都在 SetTarget
(由 Target
setter 使用)和 GetWeakReferenceTarget
, 由 Target
使用 setter/getter 和 TryGetTarget
.
所以可能是整个Target
/TryGetTarget
是线程安全的(从某种意义上说它们不会破坏 .NET 的内部结构),但是您需要比我更好的程序员来检查它们是否确实是 :-)
显然使用了 Target
/TryGetTarget
不会使目标对象线程安全!那是另一个问题!
关于c# - 并发使用 WeakReference<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36056873/