You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#多线程方法调用中仅执行一次许可证应用的实现疑问

问题说明

我有一个从运行时加载的程序集中获取的类,通过反射(无参构造函数)在多线程环境(基于Channels)中实例化。每个线程都会创建该类的一个实例,随后调用带多参数的Method()方法。其中一个参数包含插件自身所需的许可证密钥,该密钥仅需被应用一次。

当前实现(双重检查锁)

private static bool _IsLicenceApplied;
private readonly static object _IsLicenceAppliedInitializationLock = new object();

public void Method(Keys keys, object data)
{
    if(!_IsLicenceApplied)
    {
        lock(_IsLicenceAppliedInitializationLock)
        {
            if(!_IsLicenceApplied)
            {
                Apply(keys);
                _IsLicenceApplied = true;
            }
        }
    }
    // 使用data执行方法剩余逻辑
}

存在的疑问

我查阅了大量Stack Overflow回答、博客文章和文档,但关于以下内容的信息与观点存在冲突:

  • _IsLicenceApplied是否需要标记为volatile
  • 是否应使用Volatile类的方法读写_IsLicenceApplied
  • 是否应使用Interlocked类实现相同逻辑
  • 是否需要在代码块前后调用Thread.MemoryBarrier()

替代方案相关疑问

很多资料提到单例模式,并建议用Lazy<T>替代这类代码,但我需要将密钥传入方法并由首次执行处理,认为Lazy<T>无法实现这一点。是否有其他内置类可以满足需求?

编辑记录

  1. 在调用Apply()后添加了_IsLicenceApplied = true;
  2. 参考LazyInitializer源码后,提出以下可能方案(该方案是否可行?):
private static bool _IsLicenceApplied;
private static object _IsLicenceAppliedInitializationLock = new object();

public void Method(Keys keys, object data)
{
    if(!Volatile.Read(_IsLicenceApplied))
    {
        lock(_IsLicenceAppliedInitializationLock)
        {
            if(!Volatile.Read(_IsLicenceApplied))
            {
                Apply(keys);
                Volatile.Write(ref _IsLicenceApplied, true);
            }
        }
    }
    // 使用data执行方法剩余逻辑
}

内容的提问来源于stack exchange,提问作者Dan Def

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 00:41:00