問題 前同事編寫的對中控考勤機數據集成項目當中,打卡數據不能實時進行上傳到平臺當中,一直靠定時全量上傳來同步數據。 閱讀代碼後,發現代碼中有實時上傳數據的邏輯,但是運行一段時間後,中控zkemkeeper SDK中的事件失效,導致員工打卡數據沒有實時上傳。 原因 查看中控SDK Demo中的示例代碼 ...
問題
前同事編寫的對中控考勤機數據集成項目當中,打卡數據不能實時進行上傳到平臺當中,一直靠定時全量上傳來同步數據。
閱讀代碼後,發現代碼中有實時上傳數據的邏輯,但是運行一段時間後,中控zkemkeeper SDK中的事件失效,導致員工打卡數據沒有實時上傳。
原因
查看中控SDK Demo中的示例代碼,發現實現邏輯是一樣的。唯一不同的是demo使用的是winform項目編寫,打卡機同步項目是用windows服務項目編寫的。
發現中控考勤機 zkemkeeper SDK是COM組件封裝,這和winform窗體控制項是一樣的,基於消息迴圈機制。例如:winfrom項目當中 main函數都這樣啟動主窗體 Application.Run(new form1());
也就是說當你實現sdk類的時候,不線上程中進行消息迴圈,就有可能導致事件失效。
解決方式
定位了可能導致問題的原因,我對考勤機數據獲取類進行如下改動:
1. 為了簡單將連接連接打卡機設備和觸發打卡的方法直接移動到一個form當中去
FrmEquipment frmEquipment = new FrmEquipment();//form窗體中實現打卡機數據觸發事件邏輯
2. 在啟動打卡機連接的線程中聲明為 STAThread
Thread equipmentThread = new Thread(StartEquipmentForm); equipmentThread.IsBackground = true; equipmentThread.SetApartmentState(ApartmentState.STA); equipmentThread.Start();
/// <summary>
/// 啟動設備連接from
/// </summary>
[STAThread]
private void StartEquipmentForm()
{
Application.Run(frmEquipment);
}
3. 關閉數據集成服務時 跨線程 使用 form.Invoke 通知窗體關閉連接
frmEquipment.Invoke(new Action(() => { frmEquipment.Close(); }));
經過幾天測試基本運行穩定,基本確定打卡機事件觸發失效是由於原服務,沒有對COM組件運行於單線程【STA】單元消息迴圈造成的。