public static async Task <TReturn> ReadStreamAsync <TReturn>(this IWebReader webReader, Uri url, Retry retry, Func <Uri, Stream, CancellationToken, Task <TReturn> > reader, CancellationToken cancellationToken) { TReturn @return; while (true) { using (IWebStreamResponse webStreamAsync = await webReader.GetWebStreamAsync(url, false, cancellationToken, (Uri)null, new long?(), new long?(), (WebResponse)null)) { if (webStreamAsync.IsSuccessStatusCode) { Uri actualUrl = webStreamAsync.ActualUrl; using (Stream stream = await webStreamAsync.GetStreamAsync(cancellationToken).ConfigureAwait(false)) { @return = await reader(actualUrl, stream, cancellationToken).ConfigureAwait(false); break; } } else { if (!RetryPolicy.IsRetryable((HttpStatusCode)webStreamAsync.HttpStatusCode)) { webStreamAsync.EnsureSuccessStatusCode(); } bool canRetry = await retry.CanRetryAfterDelayAsync(cancellationToken).ConfigureAwait(false); if (!canRetry) { webStreamAsync.EnsureSuccessStatusCode(); } } } } return(@return); }