public async Task TestMethod2() { CompactLog log = new CompactLog(); await log.Add("文字{0}", new object[] { 1 }); Assert.AreEqual(1, log.EntryCount); var entry_create_time = log.GetEntry()[0].StartTime; log.WriteToLog((text) => { Assert.AreEqual(true, text.Contains("文字1")); }); // entry 的时间在 WriteToLog() 以后不会变 Assert.AreEqual(entry_create_time, log.GetEntry()[0].StartTime); log.RemoveEntry("文字{0}"); Assert.AreEqual(0, log.EntryCount); await log.Add("文字{0}", new object[] { 2 }); Assert.AreEqual(1, log.EntryCount); log.WriteToLog((text) => { Assert.AreEqual(false, text.Contains("文字1")); Assert.AreEqual(true, text.Contains("文字2")); }); }
void FlushCompactLog() { if (_compactLog == null) { return; } int minutes = 10; // 分钟数 TimeSpan delta = TimeSpan.FromMinutes(minutes); // 10 if (DateTime.Now - _lastFlushTime > delta) { _lastErrorCount += _compactLog.WriteToLog((text) => { Program.MainForm.OutputHistory(text, 2); }); _lastFlushTime = DateTime.Now; if (_lastErrorCount > 200 * minutes) // 200 相当于一分钟连续报错的量 { // 触发重启全部读卡器 Program.MainForm?.BeginRefreshReaders("connected", new CancellationToken()); Program.MainForm?.Speak("尝试重新初始化全部读卡器"); _lastErrorCount = 0; } } }
// 把紧凑日志写入日志文件 public void TryFlushCompactLog() { _compactLog?.WriteToLog((text) => { LibraryManager.Log?.Error(text); }); }
public async Task TestMethod3() { CompactLog log = new CompactLog(); await log.Add("文字{0}", new object[] { 1 }); Assert.AreEqual(1, log.EntryCount); var entry_create_time = log.GetEntry()[0].StartTime; log.WriteToLog((text) => { Assert.AreEqual(true, text.Contains("文字1")); }, "reset_start_time"); // entry 依然存在 Assert.AreEqual(1, log.EntryCount); // 但 entry.TotalCount 已经被清除 Assert.AreEqual(0, log.GetEntry()[0].TotalCount); // entry.Datas 也被清除 Assert.AreEqual(0, log.GetEntry()[0].Datas.Count); // entry 的时间在 WriteToLog() 以后会变 Assert.AreNotEqual(entry_create_time, log.GetEntry()[0].StartTime); // 变成 DateTime.MinValue Assert.AreEqual(DateTime.MinValue, log.GetEntry()[0].StartTime); // entry.TotalCount 为空的情况下调用 WriteToLog() 是不会输出的 int write_count = 0; log.WriteToLog((text) => { write_count++; }); Assert.AreEqual(0, write_count); }
// parameters: // reader_name_list 读卡器名字列表。形态为 "*" 或 "name1,name2" 或 "name1:1|2|3|4,name2" // style 如果为 "getTagInfo",表示要在结果中返回 TagInfo ListTagsResult _listTags(string reader_name_list, string style) { InventoryResult result = new InventoryResult(); if (Program.MainForm.ErrorState != "normal") { return new ListTagsResult { Value = -1, ErrorInfo = $"{Program.MainForm.ErrorStateInfo}", ErrorCode = $"state:{Program.MainForm.ErrorState}" } } ; List <OneTag> tags = new List <OneTag>(); // uid --> OneTag Hashtable uid_table = new Hashtable(); foreach (Reader reader in Program.Rfid.Readers) { #if NO if (reader_name == "*" || reader.Name == reader_name) { } else { continue; } #endif // 顺便要从 reader_name_list 中解析出天线部分 if (Reader.MatchReaderName(reader_name_list, reader.Name, out string antenna_list) == false) { continue; } InventoryResult inventory_result = Program.Rfid.Inventory(reader.Name, antenna_list, style // "" ); /* * // testing * inventory_result.Value = -1; * inventory_result.ErrorInfo = "模拟 inventory 出错"; * inventory_result.ErrorCode = "test"; */ if (inventory_result.Value == -1) { // TODO: 统计单位时间内出错的总数,如果超过一定限度则重新初始化全部读卡器 _ = _compactLog.Add("inventory 出错: {0}", new object[] { inventory_result.ErrorInfo }); _inventoryErrorCount++; // 每隔一段时间写入日志一次 if (DateTime.Now - _lastCompactTime > _compactLength) { _compactLog?.WriteToLog((text) => { Log.Logger.Error(text); Program.MainForm.OutputHistory(text, 2); }); _lastCompactTime = DateTime.Now; if (_inventoryErrorCount > 10) { // 发出信号,重启 Program.MainForm.RestartRfidDriver($"因最近阶段内 inventory 出错次数为 {_inventoryErrorCount}"); _inventoryErrorCount = 0; } } return(new ListTagsResult { Value = -1, ErrorInfo = inventory_result.ErrorInfo, ErrorCode = inventory_result.ErrorCode }); } foreach (InventoryInfo info in inventory_result.Results) { OneTag tag = null; if (uid_table.ContainsKey(info.UID)) { // 重复出现的,追加 读卡器名字 tag = (OneTag)uid_table[info.UID]; tag.ReaderName += "," + reader.Name; } else { // 首次出现 tag = new OneTag { Protocol = info.Protocol, ReaderName = reader.Name, UID = info.UID, DSFID = info.DsfID, AntennaID = info.AntennaID, // 2019/9/25 // InventoryInfo = info // 有些冗余的字段 }; /* * // testing * tag.AntennaID = _currenAntenna; * if (DateTime.Now - _lastTime > TimeSpan.FromSeconds(5)) * { * _currenAntenna++; * if (_currenAntenna > 50) * _currenAntenna = 1; * _lastTime = DateTime.Now; * } */ uid_table[info.UID] = tag; tags.Add(tag); } if (StringUtil.IsInList("getTagInfo", style) && tag.TagInfo == null) { // TODO: 这里要利用 Hashtable 缓存 GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { tag.TagInfo = null; // TODO: 如何报错?写入操作历史? // $"读取标签{info.UID}信息时出错:{result0.ToString()}" } else { tag.TagInfo = result0.TagInfo; } } #if NO GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { // TODO: 如何报错?写入操作历史? Program.MainForm.OutputText($"读取标签{info.UID}信息时出错:{result0.ToString()}", 2); continue; } LogicChip chip = LogicChip.From(result0.TagInfo.Bytes, (int)result0.TagInfo.BlockSize, "" // result0.TagInfo.LockStatus ); Element pii = chip.FindElement(ElementOID.PII); if (pii == null) { Program.MainForm.Invoke((Action)(() => { // 发送 UID SendKeys.SendWait($"uid:{info.UID}\r"); })); } else { Program.MainForm.Invoke((Action)(() => { // 发送 PII SendKeys.SendWait($"pii:{pii.Text}\r"); })); } #endif } } return(new ListTagsResult { Results = tags }); #if NO InventoryResult result = new InventoryResult(); List <OneTag> tags = new List <OneTag>(); _lockTagList.EnterReadLock(); try { foreach (OneTag tag in _tagList) { if (reader_name == "*" || tag.ReaderName == reader_name) { tags.Add(tag); } } return(new ListTagsResult { Results = tags }); } finally { _lockTagList.ExitReadLock(); } #endif }