当其他线程使用Dictionary时,在Dictionary中合并修改的好方法是什么?

时间:2016-04-21 10:58:46

标签: c# multithreading concurrency immutability

我正在为卡车骑行制作调度程序,通过减少死角来最小化驾驶总成本。我的计划分为两个阶段:进行初步规划和优化规划。规划目前保存为Dictionary<Truck, List <Trip>>。在这里,每辆卡车必须按照行程列表的顺序驾驶所有行程。行程的顺序与列表的顺序相同。

使用Munkres算法在截止日期的不同阶段创建初始计划。如果初始计划准备就绪,它将通过不断发展的遗传算法进行优化。在GA中,很多线程都试图改进计划。一个线程可以工作如下:

  1. 获取当前时间表。
  2. 随机更改卡车的行程顺序或更改卡车行程的分配。
  3. 检查修改后的计划中是否仍有截止日期。如果不是再次从1开始,否则继续。
  4. 通过修改检查计划成本是否降低。如果不是再次从1开始,否则继续。
  5. 设置/合并/更改计划。
  6. 步骤3和4是非常昂贵的操作(可能需要超过500毫秒)。我考虑将计划保存为ImmutableDictionary而不是Dictionary,以便在步骤1到工作计划后不会被其他线程更改。然后问题是:如何做第5步。知道如何处理这个问题吗?或者我应该采用除ImmutableDictionary想法之外的其他方式吗?

    使它更通用:合并其他线程也在使用的Dictionary的好方法是什么?

1 个答案:

答案 0 :(得分:1)

这听起来像是您使用ConcurrentDictionary详细here on MSDN的好处。这已被评论员称呼,但仍然值得正式陈述。

您可以将此与Lazy<T>结合使用,以获得一些极其强大且线程安全的代码。结帐this article一起使用两者。这是.NET Fiddle详细说明其用法。

static readonly ConcurrentDictionary<Guid, Lazy<T>> MostRecentData =
            new ConcurrentDictionary<Guid, Lazy<T>>();

然后你可以走到MostRecentData变量并调用它的方法,比如.AddOrUpdate等。这个特别需要两个工厂lambdas来评估字典的添加和密钥更新已经存在了。