![](/img/trans.png)
[英]c# - ConcurrentDictionary.TryGet(): Do I need to use while?
[英]Should I use a lock object while Cloning a ConcurrentDictionary in C#?
我有一个代码库,其中多个线程正在ConcurrentDictionary
中编写,每60秒另一个线程运行并克隆主CD,将其清除,然后继续在克隆的CD上工作。 我想知道如果我在Cloning and Clearing
主CD时不使用lock
会丢失一些数据吗? 演示此问题的代码如下:
class Program
{
static object lock_obj = new object();
static async Task Main(string[] args)
{
ConcurrentDictionary<string, ThreadSafeLong> cd = new ConcurrentDictionary<string, ThreadSafeLong>();
Func<Task> addData = () =>
{
return Task.Run(async () =>
{
var counter = 1;
while (true)
{
lock (lock_obj)
{
for (int i = 0; i < 100_000; i++)
{
cd.TryAdd($"{counter}:{i}", new ThreadSafeLong(i));
//WriteLine(i);
}
WriteLine($"Round {counter}");
}
counter++;
await Task.Delay(1_000);
}
});
};
Func<Task> writeData = () =>
{
return Task.Run(async () =>
{
while (true)
{
var sw = Stopwatch.StartNew();
lock (lock_obj) // to clone the data, and prevent any other data to be added while clone
{
var cloned = new ConcurrentDictionary<string, ThreadSafeLong>(cd);
cd.Clear();
WriteLine($"Cloned Count: {cloned.Count}");
}
sw.Stop();
WriteLine($"Elapsed Time: {sw.ElapsedMilliseconds}");
await Task.Delay(6_000);
}
});
};
await Task.WhenAll(addData(), writeData());
}
}
PS:某种程度上可能与这里的问题有关
在这些情况下,我将字典替换为新字典,而不是调用clear:
lock (lock_obj)
{
var cloned = cd;
cd = new ConcurrentDictionary<string, ThreadSafeLong>();
}
在这种情况下,其他线程将完成对旧线程的写入或已经使用新线程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.