如何防止Timer线程删除该项,而该项可能在另一个线程中使用
本文关键字:线程 另一个 Timer 何防止 删除 | 更新日期: 2023-09-27 18:30:11
我正在为RFID标签编写软件,并面临并发问题。
在我的软件中,标签具有用户定义的以分钟为单位的"寿命"。一旦读取了标签,它就会被放在ConcurrentDictionary<string, Tripple> SeenEnoughDict
中(字符串是标签的ID,而Tripple
是保持System.Threading.Timer
的struct
,还有一些东西,比如标签被看到的次数)。拥有Timer
的原因,这样标签就不会阻塞SeenEnoughDict
。Timer
调度要在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
)启动并从字典中删除该项。
我应该如何正确地锁定字典中的项目?
一旦您手头有项目(由TryGetValue返回),另一个线程可能会将其从字典中删除,但这不会导致实际对象被销毁,因为您有对它的引用。