// 从缓存中获取标签信息 static GetTagInfoResult GetTagInfo(delegate_getTagInfo getTagInfo, string reader_name, string uid, uint antenna) { //if (channel.Started == false) // return new GetTagInfoResult { Value = -1, ErrorInfo = "RFID 通道尚未启动" }; TagInfo info = (TagInfo)_tagTable[uid]; if (info == null) { var result = getTagInfo(reader_name, uid, antenna); if (result.Value == -1) { return(result); } info = result.TagInfo; if (info != null) { if (_tagTable.Count > 1000) { _tagTable.Clear(); } _tagTable[uid] = info; } } return(new GetTagInfoResult { TagInfo = info }); }
/* * public static int TagTableCount * { * get * { * return _tagTable.Count; * } * } */ // 获取标签信息 static GetTagInfoResult GetTagInfo(delegate_getTagInfo getTagInfo, string reader_name, string uid, uint antenna) { var result = getTagInfo(reader_name, uid, antenna); if (result.Value == -1) { return(result); } var info = result.TagInfo; return(new GetTagInfoResult { TagInfo = info }); }
// parameters: // readerNameList list中包含的内容的读卡器名(列表)。注意 list 中包含的标签,可能并不是全部读卡器的标签。对没有包含在其中的标签,本函数需要注意跳过(维持现状),不要当作被删除处理 // 异常: // public static void Refresh(// BaseChannel<IRfid> channel, string readerNameList, List <OneTag> list_param, delegate_getTagInfo getTagInfo, delegate_notifyChanged notifyChanged, delegate_setError setError) { setError?.Invoke("rfid", null); // 对 list 里面的元素要按照天线号进行过滤 // 注:这样过滤主要是为了防范 shelf.xml 对 M201 这样的没有多天线的配置了多个天线用于多个门,引起这里算法故障(在 Tags 中填充很多重复 UID 的对象) // 由于 RfidCenter 中 ListTags() 对于 M201 这样的读卡器没有严格过滤天线号,所以会有上述问题 // 若加固了 RfidCenter 以后,这一段过滤代码可以省略,以便提高执行速度 List <OneTag> list = new List <OneTag>(); foreach (OneTag tag in list_param) { if (InRange(tag, readerNameList) == false) { continue; } list.Add(tag); } List <TagAndData> new_books = new List <TagAndData>(); List <TagAndData> error_books = new List <TagAndData>(); // 从当前列表中发现已有的图书。用于交叉运算 List <TagAndData> found_books = new List <TagAndData>(); // 即便是发现已经存在 UID 的标签,也要再判断一下 Antenna 是否不同。如果有不同,要进行变化通知 // 从当前列表中发现(除了 UID) 内容有变化的图书。这些图书也会进入 found_books 集合 List <TagAndData> changed_books = new List <TagAndData>(); foreach (OneTag tag in list) { // 检查以前的列表中是否已经有了 var book = FindBookTag(tag.UID); /* * // 2020/4/19 验证性做法:从一个读卡器变动到另一个读卡器,第一种顺序,瞬间集合里面可能会有相同 UID 的两个对象 * // 用 Test_transfer_test_1() 单元测试 * // 如果找到的对象是属于当前读卡器以外的范围,则当作没有找到处理 * if (book != null && InRange(book.OneTag, readerNameList) == false) * book = null; */ if (book != null) { found_books.Add(book); if (book.OneTag.AntennaID != tag.AntennaID || book.OneTag.ReaderName != tag.ReaderName) { var onetag = book.OneTag; // 修改 AntennaID onetag.AntennaID = tag.AntennaID; onetag.ReaderName = tag.ReaderName; if (onetag.TagInfo != null) { /* * // TODO: 这里还有个做法,就是干脆把 .TagInfo 设置为 null。这会导致重新获取 TagInfo(所谓两阶段) * onetag.TagInfo = null; * ClearTagTable(onetag.UID); */ onetag.TagInfo.AntennaID = tag.AntennaID; onetag.TagInfo.ReaderName = tag.ReaderName; // 只清理缓存 _tagTable.Remove(onetag.UID); } changed_books.Add(book); } if (string.IsNullOrEmpty(book.Error) == false) { error_books.Add(book); } continue; } // ISO15693 的则先添加到 _books 中。等类型判断完成,有可能还要调整到 _patrons 中 book = new TagAndData { OneTag = tag }; new_books.Add(book); // 2020/4/19 // 对于新加入的标签,只清理缓存。防止以前残留的 cache 信息污染 _tagTable.Remove(tag.UID); } List <TagAndData> remove_books = new List <TagAndData>(); // 交叉运算 // 注意对那些在 readerNameList 以外的标签不要当作 removed 处理 foreach (TagAndData book in _tags) { if (InRange(book.OneTag, readerNameList) == false) { continue; } if (found_books.IndexOf(book) == -1) { remove_books.Add(book); } } bool array_changed = false; // 兑现添加 lock (_sync_tags) { foreach (TagAndData book in new_books) { if (_tags.IndexOf(book) == -1) { _tags.Add(book); array_changed = true; } } // 兑现删除 foreach (TagAndData book in remove_books) { _tags.Remove(book); array_changed = true; } } // 通知一次变化 if (array_changed || changed_books.Count > 0 || new_books.Count > 0 || remove_books.Count > 0) { notifyChanged?.Invoke(new_books, changed_books, remove_books); } List <TagAndData> news = new List <TagAndData>(); news.AddRange(_tags); new_books = new List <TagAndData>(); remove_books = new List <TagAndData>(); // .TagInfo 是否发生过填充 bool taginfo_changed = false; { List <TagAndData> update_books = new List <TagAndData>(); // 逐个获得新发现的 ISO15693 标签的详细数据,用于判断图书/读者类型 foreach (TagAndData data in news) { OneTag tag = data.OneTag; if (tag == null) { continue; } if (tag.TagInfo != null && data.Error == null) { continue; } if (tag.Protocol == InventoryInfo.ISO14443A) { continue; } if (getTagInfo != null) { // 自动重试一次 GetTagInfoResult gettaginfo_result = null; for (int i = 0; i < 2; i++) { // gettaginfo_result = GetTagInfo(channel, tag.ReaderName, tag.UID, tag.AntennaID); gettaginfo_result = GetTagInfo(getTagInfo, tag.ReaderName, tag.UID, tag.AntennaID); if (gettaginfo_result.Value != -1) { break; } } if (gettaginfo_result.Value == -1) { setError?.Invoke("rfid", gettaginfo_result.ErrorInfo); // TODO: 是否直接在标签上显示错误文字? data.Error = gettaginfo_result.ErrorInfo; update_books.Add(data); continue; } else { if (string.IsNullOrEmpty(data.Error) == false) { data.Error = null; update_books.Add(data); } } TagInfo info = gettaginfo_result.TagInfo; // 记下来。避免以后重复再次去获取了 if (tag.TagInfo == null && info != null) { tag.TagInfo = info; taginfo_changed = true; { if (update_books.IndexOf(data) == -1) { update_books.Add(data); } } } } } // end of foreach array_changed = false; // 再次兑现添加和删除 // 兑现添加 lock (_sync_tags) { foreach (TagAndData book in new_books) { _tags.Add(book); array_changed = true; } // 兑现删除 foreach (TagAndData book in remove_books) { _tags.Remove(book); array_changed = true; } } // 再次通知变化 if (array_changed == true || taginfo_changed == true || new_books.Count > 0 || update_books.Count > 0 || remove_books.Count > 0) { notifyChanged?.Invoke(new_books, update_books, remove_books); } } }