【问题标题】:C# Concurrency: Writing on different object propertiesC# 并发:编写不同的对象属性
【发布时间】:2016-12-28 15:05:46
【问题描述】:

我有以下情况:我有一个 C# 字典,它有一个 int 作为键(唯一 ID)和一个自定义类作为值,例如Dictionary<int, CustomClass>(不是ConcurrentDictionary)。如果我生成多个线程,这些线程都在整个字典的不同类属性上设置数据,它是线程安全的吗?对字典的所有add操作都在线程设置数据之前完成。

用代码更新(稍微清楚一点):

class Foo {
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop3 { get; set; }
}

// Initialized with 100 entries - Keys: 0 to 99
Dictionary<int, Foo> dict = new Dictionary<int, Foo>();

List<Task> tasks = new List<Task>();

tasks.Add(Task.Factory.StartNew(() => {
    for(int i = 0; i < dict.Count; i++) {
        dict[i].Prop1 = "whatever";
    }
}));

tasks.Add(Task.Factory.StartNew(() => {
    for(int i = 0; i < dict.Count; i++) {
        dict[i].Prop2 = "whatever";
    }
}));

tasks.Add(Task.Factory.StartNew(() => {
    for(int i = 0; i < dict.Count; i++) {
        dict[i].Prop3 = "whatever";
    }
}));

Task.WaitAll(tasks.ToArray());

【问题讨论】:

  • 考虑使用lock 语句使您的操作线程安全。
  • 是否有任何线程正在访问该对象的相同对象/值或属性?这些操作中的任何一个都依赖于读取属性值,还是仅仅设置它们?
  • 提供有关您计划如何处理这些对象的更多详细信息将很有帮助。如果您从不同的线程读取和写入属性值,则可能存在影响属性值的竞争条件。最简单的解决方案是为每个值设置一个object,在与对象交互时设置为lock,但这可能有点矫枉过正。
  • 每个线程将数据写入自定义类的不同属性,但写入字典的所有项目。所以没有两个线程将数据写入同一个属性,但至少有两个线程将数据写入同一个对象的不同属性。
  • 我不会指望将来没有代码更改会搞砸事情,所以我会使用ConcurrentDictionary 并使整个读/写线程安全。我的意思是,为什么不以好的方式去做呢?现在节省时间与未来不可预测的行为?

标签: c# multithreading dictionary


【解决方案1】:

当 2 个或更多代码块访问同一资源时,会发生竞争条件,更改其状态,并且更改本身和/或这些块的行为取决于块本身的特定执行顺序。

因此,如果您的线程之间在同一资源上的执行没有任何依赖关系,那么您可以忽略它们是否同时访问它。

虽然它们中的每一个都对其正在访问的属性进行“可见”更改很重要,并且属性之间关于它们的值存在一些依赖关系,例如,一个属性在分配时会影响某些属性的值另一个,那么,您必须同步对该属性的访问。

【讨论】:

    【解决方案2】:

    如果不同的线程正在编辑同一个对象的不同属性,那么是的,它是安全的。如果您尝试从多个线程编辑同一对象的同一属性,您将遇到竞争条件。

    这是假设属性没有引用共享状态,这是您的代码示例所显示的。

    【讨论】:

    • 不同的属性可能仍在使用某种共享状态,因此根据提供的信息,您实际上无法知道它是安全的。
    • 问题显示代码,没有共享状态...但无论如何都添加了注释。不确定投反对票的目的是什么,要么人们感到困惑,要么他们只是不知道。
    • 您在显示代码之前已回答。如果您仅在显示代码后回答,那将是不同的。
    猜你喜欢
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 2019-10-22
    • 1970-01-01
    • 2016-04-06
    • 2011-01-06
    • 1970-01-01
    相关资源
    最近更新 更多