static void Main(string[] args) { List <string> removeHashes = new List <string>(); Dictionary <string, MetricsTorrent> torrentMetrics = new Dictionary <string, MetricsTorrent>(); CLOptions options = null; Parser.Default.ParseArguments <CLOptions>(args) .WithParsed <CLOptions>(o => { options = o; }); Console.WriteLine($"Starting Prometheus scrape listener on {options.PrometheusAddress}:{options.PrometheusPort}"); var promServer = new MetricServer(options.PrometheusAddress, options.PrometheusPort); promServer.Start(); Console.WriteLine($"Creating qbittorrent WebAPI client on {options.QbittorrentIpAddress}:{options.QbittorrentPort}"); QBittorrentClient client = new QBittorrentClient(new Uri($"http://{options.QbittorrentIpAddress}:{options.QbittorrentPort}")); bool reconnectRequired = true; for (; ;) { try { if (reconnectRequired) { try { var logoutTask = client.LogoutAsync(); logoutTask.Wait(); } catch { } var loginTask = client.LoginAsync(options.QbittorrentUsername, options.QbittorrentPassword); loginTask.Wait(); } reconnectRequired = false; if (options.Verbose) { Console.WriteLine($"Processing Qbittorrent Poll at {DateTime.Now}"); } var getTorrentListTask = client.GetTorrentListAsync(); getTorrentListTask.Wait(); var response = getTorrentListTask.Result; if (response != null) { foreach (var trackedTorrent in torrentMetrics) { trackedTorrent.Value.BeginPoll(); } // summarize all sub-torrent data foreach (var torrent in response) { if (torrentMetrics.ContainsKey(torrent.Hash)) { torrentMetrics[torrent.Hash].UpdateStatus(torrent); } else { var newTorrent = new MetricsTorrent(torrent, options); torrentMetrics.Add(torrent.Hash, newTorrent); newTorrent.UpdateStatus(torrent); } } foreach (var trackedTorrent in torrentMetrics) { trackedTorrent.Value.EndPoll(); if (trackedTorrent.Value.TorrentDeleted) { removeHashes.Add(trackedTorrent.Value.Hash); } } foreach (var item in removeHashes) { torrentMetrics.Remove(item); } removeHashes.Clear(); } } catch (Exception ex) { Console.WriteLine($"Fatal Error: {ex.Message}"); reconnectRequired = true; } System.Threading.Thread.Sleep(TimeSpan.FromSeconds(options.QbitorrentPollSeconds)); } }