【问题标题】:Is this static method thread-safe?这个静态方法是线程安全的吗?
【发布时间】:2016-07-16 18:26:57
【问题描述】:

我有以下课程:

public static class MetadataManager
{
    // assume that it is thread safe
    public static List<Field> FieldRegistry { get; set; }
}

public class Field
{
    public int ID { get; set; }
    public string Name { get; set; }
}



public static class FieldDataValidationManager
{
    public static bool Validate(int fieldID)
    {
        return MetadataManager.FieldRegistry.FirstOrDefault(f => f.ID == fieldID).ID > 1;
    }

    public static bool Validate(Field field)
    {
        return fieldID.ID > 1;
    }
}

现在, User1和User2同时调用静态方法,并发有问题吗?

FieldDataValidationManager.Validate(111) 

或 用户 1 正在执行 FieldDataValidationManager.Validate(field1) 和 User2 正在执行 FieldDataValidationManager.Validate(field2)

【问题讨论】:

    标签: c# multithreading methods static


    【解决方案1】:

    是的,您的代码是线程安全的,因为您的代码只是从列表中读取。静态与否根本无关紧要。

    如果List&lt;T&gt; 上有写操作,您可能会遇到并发问题。那么你应该使用ConcurrentBag&lt;T&gt; 或其他线程安全的集合类型。

    【讨论】:

      【解决方案2】:

      只要不改变FieldRegistry列表的内容,就不存在并发问题。
      但是您没有显示填写该列表的位置。因此,如果您的实际代码确实在该列表中插入或删除条目,而其他线程正在调用Validate,则会出现问题(Patrick Hofman 建议的ConcurrentBag&lt;T&gt; 可能是一个不错的选择) .


      但你实际上想在这里做什么:

      public static bool Validate(int fieldID)
      {
          return MetadataManager.FieldRegistry.FirstOrDefault(f => f.ID == fieldID).ID > 1;
      }
      

      因此,如果已经有一个带有ID 的条目,那么您的fieldID 似乎是有效的并且ID 大于1
      好的,但是如果fieldID 尚未包含在您的列表中,您的方法将抛出NullReferenceException。所以你最好把这个方法改成这样:

      public static bool Validate(int fieldID)
      {        
          return 
              MetadataManager.FieldRegistry.Any(f => f.ID == fieldID) &&
              fieldID > 1;
      }
      

      【讨论】:

      • 亲爱的雷内。我同意你的看法,但这只是举例。
      猜你喜欢
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 2013-08-28
      • 1970-01-01
      • 2016-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多