【发布时间】:2016-02-21 22:43:13
【问题描述】:
我在我的代码中使用了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());
}
}
【问题讨论】:
-
那么你需要在你自己实现
IDictionary<K, V>的每个方法上使用课程lock。 -
即使这样做,尽管您只是将问题推到字典之外。您只是无法知道另一个线程正在锁后面等待更新值。因此,最新的值可能已经计算出来,但没有在字典中更新。
-
能否请您发布您的代码,而不是您在问题中发布的模糊的五个步骤?
-
我已经添加了上面的代码。请建议。谢谢。
-
你会得到最后写的。如果一个线程在一纳秒后更新字典条目,那么你读到的不再是最后一个。 ConcurrentDictionary 是线程安全的,它不会自动使用线程安全的方式。