我正在为RFID标签编写软件并面临并发问题。
在我的软件中,标签具有用户定义的&#34;生命周期&#34;用分钟计算。一旦标记被读取,它就会放在ConcurrentDictionary<string, Tripple> SeenEnoughDict
中(字符串是标记的ID,而Tripple
是struct
,它会保留System.Threading.Timer
以及其中的一些内容标签被看到的次数)。拥有Timer
背后的原因,以便标签不会阻塞SeenEnoughDict
。 Timer
计划在{1}}生命周期结束时从SeenEnoughDict
删除标记。
Parallel.ForEach(_myReaderTC.Cast<Tag>(), t => // _myReaderTC is tag collection that
//comes back from hardware.
{
Tripple temp_tripple;
// is it in dict ?
if (SeenEnoughDict.TryGetValue(t.ID, out temp_tripple))
{
// Antenna different from prev read ?
if (temp_tripple.prev_antenna != t.Antenna)
{
temp_tripple.prev_antenna = t.Antenna;
temp_tripple.num_of_times_seen = 1;
return;
}
// antennas are the same, was it seen enough times on particular antenna ?
if (temp_tripple.num_of_times_seen == _myCaptRespConf.valid_reads)
{
// Remove tag id from the dictionary, and delete it's timer
Tripple temp;
SeenEnoughDict.TryRemove(t.ID, out temp);
temp.timer.Dispose();
}
// have not seen it enough times
else
{
temp_tripple.num_of_times_seen++;
return;
}
}
// not in the dict
else
{
// add the tag's id to the dict and schedule it for deletion
SeenEnoughDict.TryAdd(t.ID,
new Tripple(t.Antenna,
new Timer(
// lamda; schedule tags for deletion
(Object tagID) => {
Tripple temp;
// from temp dict
SeenEnoughDict.TryRemove((string)tagID, out temp);
temp.timer.Dispose();
},
t.ID, // parameter to lambda
// _myCaptRespConf.TagPersistence is tags lifecycle time in minutes
new TimeSpan(0, 0, _myCaptRespConf.TagPersistence, 0, 0),
new TimeSpan(0, 0, 0, 0, -1))));
return;
}
}
如果查看我的代码,很有可能获得竞争:当一个线程通过if (SeenEnoughDict.TryGetValue(t.ID, out temp_tripple)) {....}
,第二个线程(Timer
)启动并删除该项目时字典。
如何正确锁定字典中的项目?
答案 0 :(得分:1)
一旦你掌握了项目(由TryGetValue返回),另一个线程可能会从字典中删除它,但这不会导致实际对象被销毁,因为你有一个对它的引用。