我在代码中使用ConcurrentDictionary
(ongoingConnectionDic
):
ongoingConnectionDic
。我的问题是,我可以确保在执行读取操作时,没有其他线程同时写入/更新值吗?那么,我是否正在阅读字典的最新价值?
如果没有,我如何实现我的目标?
示例程序:
class Program
{
// Dictionary in question
private static ConcurrentDictionary<string, string> ongoingPrinterJobs =
new ConcurrentDictionary<string, string>();
private static void sendPrint(string printerName)
{
if (ongoingPrinterJobs.ContainsKey(printerName))
{
// Add to pending list and run a thread to finish pending jobs by calling print();
}
else
{
ongoingPrinterJobs.TryAdd(printerName, ""); // -- Add it to the dictionary so that no other thread can
// use the printer
ThreadPool.QueueUserWorkItem(new WaitCallback(print), printerName);
}
}
private static void print(object stateInfo)
{
string printerName = (stateInfo as string);
string dummy;
// do printing work
// Remove from dictionary
ongoingPrinterJobs.TryRemove(printerName, out dummy);
}
static void Main(string[] args)
{
// Run threads here in random to print something on different printers
// Sample run with 10 printers
Random r = new Random();
for ( int i = 0 ; i < 10 ; i++ )
{
sendPrint(r.Next(0, 10).ToString());
}
}
答案 0 :(得分:1)
并发集合采用&#34;快照&#34;在列举时的集合。这是为了防止枚举器在另一个线程出现并写入集合时变为无效。
ContainsKey
之类的方法可以枚举字典中的项目(您必须查看实现),在这种情况下,您可能正在阅读陈旧数据。
允许您执行的所有并发集合确保您可以枚举集合,即使在您枚举时另一个线程写入它也是如此。标准集合的情况并非如此。
话虽如此,正如其他人在评论中提到的那样,其他线程安全问题仍必须考虑(例如竞争条件)。
在您尝试读取值之后但在写入ia值之前,阻止某人将值插入集合的唯一方法是在读取值之前lock
集合,到确保在整个事务中对集合的同步访问(即读取和后续写入值)。