public void Listen() { //create reliable socket switch (Config.SocketType) { case SocketType.BareSocket: _reliableSocket = _socketFactory.GetReliableSockWithBareSocket(_logger); break; case SocketType.ThreadSocket: _reliableSocket = _socketFactory.GetReliableSockWithThreadSocket(_logger); break; default: throw new ArgumentOutOfRangeException(); } _reliableSocket.Listen(_port); _reliableSocket.AddEventCallbacks(OnReceivePacket, OnNewClientConnect, OnClientDisconnect); _lastTick = DateTime.UtcNow; _isTicking = false; _socketTickTask = TaskScheduler.ScheduleOnInterval(() => { if (_isStopping) { return; } lock (_isTickingMutex) { if (_isTicking) { return; } _isTicking = true; } var duration = (DateTime.UtcNow - _lastTick).Milliseconds; _lastTick = DateTime.UtcNow; if (duration > _maxSendDuration) // overlapping not matters { _maxSendDuration = duration; } try { _reliableSocket.Tick(); } catch { //empty } finally { lock (_isTickingMutex) _isTicking = false; } }, 0, Config.SocketTickTimeMs); //start protection _protectionManager.Start(); }