private async Task AttemptReconnect() { if (await SyncRoot.WaitAsync(0)) { try { if (State.CurrentValue.Server.IsConnected) { return; } var attempts = 1; while (true) { var(delay, jitter) = Compute.ExponentialBackoffDelay( iteration: attempts, maxDelayInMilliseconds: ReconnectMaxDelayMilliseconds); var approximateDelay = (int)Math.Ceiling((double)(delay + jitter) / 1000); Log.Information($"Waiting about {(approximateDelay == 1 ? "a second" : $"{approximateDelay} seconds")} before reconnecting"); await Task.Delay(delay + jitter); Log.Information("Attempting to reconnect (#{Attempts})...", attempts); try { // reconnect with the latest configuration values we have for username and password, instead of the // options that were captured at startup. if a user has updated these values prior to the disconnect, // the changes will take effect now. await Client.ConnectAsync(Options.CurrentValue.Soulseek.Username, Options.CurrentValue.Soulseek.Password); break; } catch (Exception ex) { attempts++; Log.Error("Failed to reconnect: {Message}", ex.Message); } } }