【问题标题】:C# Best practice for synchronizing a collectionC# 同步集合的最佳实践
【发布时间】:2016-09-03 09:40:24
【问题描述】:

鉴于以下情况,什么是最好的同步技术人员

* 请注意,这是一个示例模型,还有更多事情要做。

共享资源是从两个地方更新的仪器字典:

(1) 内部值正在快速更新。

(2) 整个集合被刷新。

  public class Insturment
  {
       public Feed Feed{ get; set;}
  }

  static IDictionary<string,Instrument> instruments = new Dictionary<string,Instrument>();

   // (1) This happens frequently  
   public void OnNewFeed(Feed feed)
   {
       instruments[feed.Symbol].Feed = feed;
   }

   // (2) happens every few hours ,or manually triggered at any given time 
   public void BuildInstruments()
   {
        foreach(var instrument in newInstruments)
        {
             instruments.AddOrUpdate(insturment.Symbol,insturment);
        }     
   }

当使用手动重置事件重建整个集合时,我想到了 UpdateFeed() 上相同的基本概念块线程。

   ManualResetEvent _mre = new ManualResetEvent(false);

   public void OnNewFeed(Feed feed)
   {
       _mre.WaitOne();
       instruments[feed.Symbol].Feed = feed;
   }

   public void BuildInstruments()
   {
        _mre.Reset();

        foreach(var instrument in newInstruments)
        {
             instruments.AddOrUpdate(insturment.Symbol,insturment);
        }

        _mre.Set();     
   }     

或者使用任何类型的任务包装器并等待它。 类似这样的构造:The anser by Stephen Cleary

  • 旁注我不关心从字典中读取数据时的数据完整性。这意味着我不介意有人在任何给定点从字典中接收未更新的值。我确实介意实际更新永远丢失,因为我刚刚更换了正在更新的整个仪器。

问题:

1) 谁能想到一种更好的方法来同步仪器字典上的操作。

2) 在包装 WaitHandle 的任务上使用 async/await 有什么好处吗? (就像上面链接中描述的那样)

【问题讨论】:

  • 使用并发字典
  • 可以说我是请描述这将如何帮助我。我很高兴你提出来了。 :) 请注意两件事,我正在替换 Build() 中的整个仪器对象,并且我不想在替换字典中的父对象时丢失新的 Feed。
  • 对不起,我误解了你的问题,算了 :),除非你期望有多个来自不同来源的 OnNewFeed,否则它对你没有帮助,抱歉这个错误。

标签: c# multithreading asynchronous


【解决方案1】:

同步集合的最佳实践

我想说最好的做法是使用lock,除非您需要别的东西。

例如,如果您需要异步锁定,您可以使用SemaphoreSlimAsyncLock 实现之一。

或者使用任何类型的任务包装器并等待它。

我不会将该解决方案用于集合同步。如果您需要异步兼容同步,则使用异步兼容同步原语(例如SemaphoreSlimAsyncLock)。如果您不需要它,则只需使用lock

Task-wrapper-around-WaitHandle 情况仅在您必须使用基于WaitHandle 的对象时才需要(例如,它在进程之间共享) 并希望使用异步代码来使用它。听起来这种情况在这里不适用。

旁注我不关心从字典中读取数据时的数据完整性。这意味着我不介意有人在任何给定点从字典中接收未更新的值。

我还是建议锁定读取。如果不这样做,可能会出现各种问题(如撕裂)。

顺便说一句:您对场景的描述一直使用“更新”一词。听起来您可能想要更多的生产者/消费者解决方案,或者可能需要像 Rx 这样的发布/订阅,而不是共享的同步集合。

【讨论】:

    猜你喜欢
    • 2010-09-06
    • 2015-05-02
    • 1970-01-01
    • 2011-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    相关资源
    最近更新 更多