如何使此 c# 属性线程安全?



我在 c# 代码中有以下代码来计算属性值:

public class Options
{
public bool UseFeature
{
public bool NoUseFeatureInternal { get; set; }
public bool UseFeatureInternal { get; set; }
get
{
// Command line param
if (NoUseFeatureInternal )
{
return false;
}
// Command line param
if (UseFeatureInternal )
{
return true;
}
if (cachedUseFeature.HasValue)
{
return cachedUseFeature.Value;
}
string userName= Override.GetUserName();
cachedUseFeature = ToolBox.Config.Flights.IsActive("FeatureName", overrideName);
return cachedUseFeature.Value;
}
}
private bool? cachedUseFeature;
}
public static class ToolBox
{
private static Lazy<GlobalConfig> configLazy = new Lazy<GlobalConfig>(() => GlobalConfig.Load() ?? GlobalConfig.Default);
public static GlobalConfigConfig
{
get
{
return configLazy.Value;
}
}
}
public class GlobalConfig
{
public static GlobalConfig Load(string filePath = null)
{
filePath = filePath ?? GetGlobalConfigPath();
if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
{
return null;
}
string fileContents = File.ReadAllText(filePath);
// Parses json
return ParseConfig(fileContents);
}
}

我从多个任务访问选项.使用功能值。 我似乎在程序的某些部分,值变为真,而有些部分则被证明是错误的,但只是在某些时候。 我的思考过程是,我知道由于多个线程,cachedUseFeature = ToolBox.Config.Flights.IsActive("UseFeature", overrideName);可以被多次调用。 但是,我不明白它如何在调用的不同时间给出不同的答案。 cachedUseFeature的惰性值会解决这个问题吗,还是还有其他事情发生? 看看 Lazy线程安全的惰性加载单例的好解决方案吗?,我很想在 Toolbox.Config 周围设置一个锁,但我不确定这是正确的解决方案。

您可以将选项设置为单例,并在单例的私有构造函数中执行以下行

cachedUseFeature = ToolBox.Config.Flights.IsActive("UseFeature", overrideName);

简单的互斥同步通常通过锁定块完成。

  1. 添加要锁定的专用对象。别人看不到的私密的东西。永远不要试图锁定你正在赠送的东西。
  2. 将所有
  3. 需要互斥的代码包装到一个锁定块中。
  4. 这确实意味着您必须编写每个 get 和 set 函数的代码。因此,不再自动实现属性。我知道没有语法糖可以让你解决这个问题。

    private object mutex = new object();
    public bool UseFeatureInternal {
    get {
    lock(mutex){
    //put all get code - including return statements - into this block
    }
    }
    set {
    lock(mutex){
    //put all set code here
    }
    }
    }
    

但正如其他人指出的那样,这可能实际上不是您正在寻找的机器人。

最新更新