Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当其他线程使用字典时,在字典中合并修改的好方法是什么?_C#_Multithreading_Concurrency_Immutability - Fatal编程技术网

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

C# 当其他线程使用字典时,在字典中合并修改的好方法是什么?,c#,multithreading,concurrency,immutability,C#,Multithreading,Concurrency,Immutability,我正在为卡车驾驶制定一个计划,通过减少死头来最大限度地降低驾驶的总成本。我的计划分为两个阶段:制定初步计划和优化计划。计划当前保存为字典。在此,每辆卡车必须按照行程列表的顺序驾驶所有行程。行程的顺序与列表的顺序相同 在截止日期的不同阶段,使用Munkres算法创建初始计划。如果初始计划准备就绪,将通过进化遗传算法对其进行优化。在GA中,许多线程试图改进调度。线程可以按如下方式工作: 获取当前计划 随机更改卡车的行程顺序或更改卡车的行程分布 检查修改后的时间表中是否仍有截止日期。如果不是从1开始,

我正在为卡车驾驶制定一个计划,通过减少死头来最大限度地降低驾驶的总成本。我的计划分为两个阶段:制定初步计划和优化计划。计划当前保存为
字典
。在此,每辆卡车必须按照行程列表的顺序驾驶所有行程。行程的顺序与列表的顺序相同

在截止日期的不同阶段,使用Munkres算法创建初始计划。如果初始计划准备就绪,将通过进化遗传算法对其进行优化。在GA中,许多线程试图改进调度。线程可以按如下方式工作:

  • 获取当前计划
  • 随机更改卡车的行程顺序或更改卡车的行程分布
  • 检查修改后的时间表中是否仍有截止日期。如果不是从1开始,否则继续
  • 检查进度计划的成本是否因修改而降低。如果不是从1开始,否则继续
  • 设置/合并/更改计划
  • 步骤3和步骤4是非常昂贵的操作(可能需要500毫秒以上)。我考虑将计划保存为
    不可变字典
    ,而不是
    字典
    ,这样在步骤1之后,工作计划不会被其他线程更改。那么问题是:如何执行步骤5。你知道我怎样才能处理好这件事吗?或者我应该用另一种方式而不是
    ImmutableDictionary
    的想法来做吗


    更一般化:合并其他线程也在使用的
    字典的好方法是什么?

    这听起来像是一个使用
    ConcurrentDictionary
    的案例。这已经被一位评论员提出,但尽管如此——仍然值得正式说明

    您可以将this与
    Lazy
    结合使用,以获得一些非常强大且线程安全的代码。同时使用两者进行结账。下面是一个详细介绍其用法的示例

    static readonly ConcurrentDictionary<Guid, Lazy<T>> MostRecentData =
                new ConcurrentDictionary<Guid, Lazy<T>>();
    
    静态只读ConcurrentDictionary MostRecentData=
    新的ConcurrentDictionary();
    

    然后,您可以找到
    MostRecentData
    变量并调用其方法,如
    .AddOrUpdate
    ,等等。这一个特别需要两个工厂lambda,它们评估字典中的一个添加项和一个更新项(如果键已经存在)。

    关于
    ConcurrentDictionary
    ()?在
    ConcurrentDictionary
    中,我找到了解决与密钥存在相关的并发问题的方法,但这些方法无法解决我的问题。如果一个线程将一个trip序列
    {t3,t8,t2,t6}
    更改为
    {t3,t2,t8,t6}
    ,而另一个线程已经将该序列更改为
    {t8,t3,t2,t6}
    ,这是一个问题。使用
    ConcurrentDictionary
    无法解决此问题。也不要使用
    ConcurrentList
    s,因为不同列表之间的行程也可以更改。还有其他想法吗?好吧,如果顺序很重要,那你为什么要使用
    字典
    ?“字典中元素的顺序是不确定的”-字典的顺序并不重要。
    列表的顺序为。正如我所说,行程是按照列表的顺序进行的。因此
    字典
    将卡车连接到
    列表
    /行程序列。列表的顺序可以更改(更改行程顺序),行程可以移动到连接到另一辆卡车(分配给另一辆卡车)的列表。。我想说的是,每个GA线程都应该有自己的数据结构副本。在每个周期之后,您使用GA找到的最佳数据结构更改基础数据结构,然后将其副本发送给另一个迭代。