【问题标题】:Lock writing a Property锁定写入属性
【发布时间】:2014-07-30 08:42:52
【问题描述】:

在我的课堂上我有这个属性:

public List<MyObject> mCollection { get; set; }

这个集合在一些不同的线程中使用。

我想做的是只在所有线程都读完mCollection时才允许写入这个属性。

类似于获取和释放令牌,并且仅在释放所有令牌时才允许写入。框架里有这样的东西吗?

提前致谢

【问题讨论】:

    标签: c# .net multithreading thread-safety locking


    【解决方案1】:

    您可以通过多种方式实现这一目标。为简单起见,请让您的读者通过彼此同步来合作。

    • 让读者使用ReaderWriterLockSlim 获取读锁。让作者获取写锁。
    • 让读者发信号CountdownEvent。让作者等着看吧。
    • 将所有读者和作者设为SignalAndWait Barrier,以便作者只有在所有人都完成后才能继续。

    选择与您的场景相匹配的内容。

    【讨论】:

    • 虽然这回答了问题,但我坚信正确的方法是使用适合多线程应用程序的结构,而不是非常复杂的锁定解决方案。
    • @SKleanthous 你可能是对的,但是对于这个问题 a)我回答了所要求的内容,b)不清楚这些结构是什么,因为很难猜测该对象的用途和列表的样子。此外,他可能需要对 Web 服务调用等副作用进行排序(他的文字表明他真的想等待)。我们不能仅仅通过使用不可变结构来解除对阅读器的阻塞。这里猜测太多了。
    • 确实,不可变集合并非没有它们的要求,但所有引入的“问题”可以通过使用良好的设计和(如果需要)其他框架(如 Dataflow)来更好地减少事件。
    • 我还想补充一点,在调用代码中使用锁可能非常容易出错,因为它取决于调用方法来协调。未来的实现者可能会错过这一点并引入错误。
    【解决方案2】:

    虽然有一些结构可以提供帮助,例如 SemaphoreSlim,但我坚信有更好的方法来解决您的问题。这可能就像使用 ImmutableList 而不是 List 并更改您的调用代码以使用它。

    在您的场景中使用锁定机制,必须由调用者和有权访问您的属性的人来实现。由于这是公开的,因此除了检索列表外,您没有任何方法强制调用者提交给锁定机制,该列表包装在 IDisposable 中,该 IDisposable 将在 dispose 时释放锁定(这有点复杂,因为您有在获取 IEnumerator 之前锁定)。然而,我再次相信,重组您的源代码以使用经过验证的构造是一个更好的解决方案。

    如果您需要链接事件或处理器,我强烈建议您使用 TPL Dataflow。这将使您摆脱当一个线程等待某些东西可用时所面临的问题,并且还将产生明显更好的设计和更易于维护的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-02
      • 1970-01-01
      相关资源
      最近更新 更多