gpt4 book ai didi

c# - 从并发字典中获取所有值并在不丢失数据的情况下清除它

转载 作者:可可西里 更新时间:2023-11-01 07:55:06 25 4
gpt4 key购买 nike

我正在向并发字典中添加/更新对象并定期(每分钟)刷新字典,所以我的代码看起来像这样:

    private static ConcurrentDictionary<string, Metric> _metrics = new ConcurrentDictionary<string, Metric>();

public static void IncrementCountMetricBy(string name, int count)
{
_metrics.AddOrUpdate(....
}

public static Metric[] Flush()
{
var flushedMetrics = _metrics;
_metrics = new ConcurrentDictionary<string, Metric>();
return flushedMetrics.Values.ToArray();
}

现在我不确定这段代码是否有可能丢失一些对象/更新

最佳答案

是的,您可能可能在那里丢失一些数据:

  1. 递增线程可以读取 _metrics 字段并获取旧字典,然后被中断
  2. 刷新线程然后用新字典替换_metrics字段
  3. 刷新线程调用了 Values.ToArray()
  4. 递增线程然后在字典上调用 AddOrUpdate,该字典不再被任何对象查看。 (它在第 1 步中获取的那个。)

换句话说,假设您的 IncrementMetricCountBy 方法实际上是:

public static void IncrementCountMetricBy(string name, int count)
{
var tmp = _metrics;
Thread.Sleep(1000);
tmp.AddOrUpdate(...);
}

如果您明白为什么这样做不安全,那么同样的论点也适用于您当前的代码。

据我所知,您可以在此处使用 ConcurrentDictionary 做任何特别简单的事情。一种选择是拍摄所有 key 的快照,然后将它们全部删除:

var keys = _metrics.Keys.ToList();
var values = new List<Metric>();
foreach (var key in keys)
{
Metric metric;
if (_metrics.TryRemove(key, out metric))
{
values.Add(metric);
}
}
return values;

返回时字典可能不是,但您不应丢失任何数据。 (您可能会在该方法启动后更新指标,并且在删除 key 后发生的任何更新最终都会重新添加它,但这应该没问题。)

关于c# - 从并发字典中获取所有值并在不丢失数据的情况下清除它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17195007/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com