public async virtual Task <LogListRoot> GetLogListRootAsync(CancellationToken cancellationToken) { var logListRoot = default(LogListRoot); var stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); if (!LogStoreService.TryGetValue(LogListRootKey, out logListRoot)) { await _logListSemaphore.WaitAsync().ConfigureAwait(false); try { if (!LogStoreService.TryGetValue(LogListRootKey, out logListRoot)) { var logListTask = LogListApi.GetLogListAsync(cancellationToken); var logListSignatureTask = LogListApi.GetLogListSignatureAsync(cancellationToken); var logListPublicKeyTask = LogListApi.GetLogListPublicKeyAsync(cancellationToken); await Task.WhenAll(logListTask, logListSignatureTask).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); var logListBytes = logListTask.Result; var logListSignatureBytes = logListSignatureTask.Result; var logListPublicKey = logListPublicKeyTask.Result; if (logListPublicKey != null || logListSignatureBytes != null) { var isValid = VerifyLogListSignature(logListBytes, logListSignatureBytes, logListPublicKey); if (!isValid) { throw new InvalidDataException("Log list failed signature verification!"); } } logListRoot = Deserialise <LogListRoot>(logListBytes); if (logListRoot?.Operators != null) { LogStoreService.SetValue(LogListRootKey, logListRoot); } foreach (var op in logListRoot?.Operators) { Console.WriteLine($"{string.Join(";", op.Email)}"); foreach (var log in op.Logs) { Console.WriteLine($" {BitConverter.ToString(Convert.FromBase64String(log.LogId)).Replace("-", string.Empty).ToLowerInvariant()} {log.Description}"); } Console.WriteLine(); } } } catch (Exception) { throw; } finally { _logListSemaphore.Release(); } } stopwatch.Stop(); return(logListRoot); }