場景:
在各辦事點安裝中控考勤儀Iface302,各辦事點的工作人員上下班報到時使用指紋或面紋進行自動登記,驗證成功后將與服務呂進行通訊記錄相關的考勤信息。
條件限制:
由於Iface302設備不支持自動連接功能,也因此需要在服務器中定時地、主動地去輪詢各辦事點的連接狀況。
問題一:
與IFace302通訊主要通過廠家對COM組件封裝的dll二次開發,在線程環境的狀態下無法訂立考勤的事件,驗證事件,類似的代碼如下:
zkemkeeper.CZKEMClass zkDevice = new zkemkeeper.CZKEMClass(); Thread th = new Thread((ThreadStart)delegate() { _isConnected = zkDevice.Connect_Net(_deviceip, _deviceport); if (_isConnected == true) { //連接成功后才能注冊 //如果斷開后事件也自然失效 if (zkDevice.RegEvent(1, 65535))//Here you can register the realtime events that you want to be triggered(the parameters 65535 means registering all) { zkDevice.OnFinger += new zkemkeeper._IZKEMEvents_OnFingerEventHandler(zkDevice_OnFinger); } }); th.IsBackground = true; th.Start();
此代碼是可以正常運行但無法注冊事件,而如果不使用線程每次調用COM組件的方法都是有一段時間的阻塞。
問題二:
經了解,博客園有人提出在線程中增加 Application.Run();代碼可以解決無法訂閱事件的問題,即:
zkemkeeper.CZKEMClass zkDevice = new zkemkeeper.CZKEMClass();
Thread th = new Thread((ThreadStart)delegate()
{
_isConnected = zkDevice.Connect_Net(_deviceip, _deviceport);
if (_isConnected == true)
{
//連接成功后才能注冊
//如果斷開后事件也自然失效
if (zkDevice.RegEvent(1, 65535))//Here you can register the realtime events that you want to be triggered(the parameters 65535 means registering all)
{
zkDevice.OnFinger += new zkemkeeper._IZKEMEvents_OnFingerEventHandler(zkDevice_OnFinger);
}
Application.Run(); //新加代碼,后是可以正常訂閱事件
});
th.IsBackground = true;
th.Start();
在代碼最后加上Application.Run()的確是可以解決無法訂閱事件的問題,但當程序運行一段時間后就會出現System.OutOfMemoryException: 引發類型為“System.OutOfMemoryException”的異常。
由於是幾個小時才出現的內存溢出異常,通過觀察任務管理器可以發現以下問題:
在多線程中使用Application.Run()方法會導致到內存使用、虛擬內存大小、頁面緩沖池、線程數是不斷地增加
最終導致“System.OutOfMemoryException”的異常。
嘀咕幾句:
在這里再次吐槽一下中控科技的售后服務極差,反復打了N次電話均無法連通,在官網留言亦無任何反饋。
尋求幫助:
各同行該問題如何解決呢?