c# - 并发使用 Wea​​kReference<T>?

标签 c# .net thread-safety weak-references

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.

但是,我想知道无论如何使用 Wea​​kReference 的实例成员是否真的安全?

特别是,我想知道允许并发访问这样的东西是否安全:

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;
    }
}

两者都是TryGetTargetSetTarget在这里使用,可能被多个线程同时调用。

它们都在调用本地代码实现的私有(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# - 并发使用 Wea​​kReference<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36056873/

相关文章:

c# - Autofac:将 OnActivated 添加到所有注册

.net - 在 .Net 应用程序中使用 Active Directory Web 服务

c# - 用于规范化具有唯一 ID 的数据库以构建数字的数据库设计

c# - 我的面向 .Net 3.5 框架的应用程序将在哪些平台上运行?

java - ConcurrentHashMap:避免使用 "putIfAbsent"创建额外的对象?

c# - 在启用强制数组的情况下将 JSON 转换为 XML 时出现问题

c# - Azure Web 作业 : Is it possible to retrieve the Host Url programmatically in the console app?

c++ - CWnd::GetSafeHwnd() 和 CWnd::m_hWnd 是线程安全的吗?

java - Trove 库是线程安全的吗?

c# - MVC 4 Async Action 不处理等待之间的多个请求