public async Task MainLoopAsync(int timeslicems) { logger.Trace("Entered loop"); var lastPing = DateTime.UtcNow; await SendPingAsync(); while (_looping) { try { await WaitEventAsync(timeslicems); } catch (OperationCanceledException) { logger.Trace("Timeout"); } finally { var now = DateTime.UtcNow; if ((now - lastPing).TotalSeconds >= 30) { await SendPingAsync(); lastPing = now; } if (ScheduledTasks != null) { logger.Trace("Running idle tasks"); ScheduledTasks.Invoke(this); ScheduledTasks = null; } IdleTasks?.Invoke(this); } } }