protected override void OnStop() { //set class level closing flag used to refuse any new UDP/TCP connections closing = true; //wait for timers to run and to allow the workertcpsockets to process any outstanding requests var shorttimeout = 5000; Thread.Sleep(shorttimeout); //disable the timers Timer_Cleanup.Enabled = false; Timer_Parse.Enabled = false; //this.timer1.Enabled = false; //this.timer2.Enabled = false; //this.timer3.Enabled = false; //this.timer4.Enabled = false; //set worker tcp socket max age to 30 seconds TimeSpan maxAge = new TimeSpan(0, 0, 30); // 30 seconds long waiting = Environment.TickCount; try { //while loop to break when socket count reaches 0 or 30s timeout expires while (m_WorkerTCPSocketList.Count > 0 && Environment.TickCount - waiting <= 30000) { WorkerTCPSocket workerObj = null; foreach (WorkerTCPSocket worker in m_WorkerTCPSocketList) { if (worker.GetAge() > maxAge) { workerObj = worker; break; } } //check to see if socket is too old if (workerObj != null) { try { workerObj.CloseAndDestroy(); } catch (Exception excep) { Logger.GetInstance().Exception("Exception on TCP Worker disposal: ", excep, string.Empty); } Thread.Sleep(100); } else { Thread.Sleep(1000); } } } catch (Exception excep) { Logger.GetInstance().Exception("Exception on age check foreach: ", excep, string.Empty); } //close main Socket Handler if (m_MainTCPSocket != null) { //if waiting for tcp socket to finish or pending connection if (!exitontcpconnect && !waitingfortcp) { Thread.Sleep(shorttimeout); } m_MainTCPSocket.Close(); } //purge and close the raw data manager if (m_RawDataManager != null) { //force all pending parses to be parsed m_RawDataManager.moveRawData(); m_RawDataManager.parseAllReadyData(m_DBWriter); m_RawDataManager.Close(); } //close the db writer m_DBWriter?.Close(); }