private Task OpenStream(Action <ISegmentMetadata> setMetadata, CancellationToken cancellationToken) { this.ThrowIfDisposed(); SM.Media.Web.WebResponse webResponse = new SM.Media.Web.WebResponse(); IRetry retry = this._retryManager.CreateRetry(2, 200, new Func <Exception, bool>(RetryPolicy.IsWebExceptionRetryable)); return(RetryExtensions.CallAsync(retry, (Func <Task>)(async() => { long?nullable1; long?nullable2; while (true) { if (this._startOffset.HasValue && this._endOffset.HasValue) { nullable1 = this._endOffset; nullable2 = this._startOffset; nullable1 = nullable1.HasValue & nullable2.HasValue ? new long?(nullable1.GetValueOrDefault() - nullable2.GetValueOrDefault()) : new long?(); long?nullable3; if (!nullable1.HasValue) { nullable2 = new long?(); nullable3 = nullable2; } else { nullable3 = new long?(nullable1.GetValueOrDefault() + 1L); } this._expectedBytes = nullable3; } else { this._expectedBytes = new long?(); } this._response = await this._webReader.GetWebStreamAsync(this._actualUrl ?? this._segment.Url, false, cancellationToken, this._segment.ParentUrl, this._startOffset, this._endOffset, webResponse).ConfigureAwait(false); if (!this._response.IsSuccessStatusCode) { HttpStatusCode statusCode = (HttpStatusCode)this._response.HttpStatusCode; if (HttpStatusCode.NotFound != statusCode && !RetryPolicy.IsRetryable(statusCode)) { this._response.EnsureSuccessStatusCode(); } bool canRetry = await retry.CanRetryAfterDelayAsync(cancellationToken).ConfigureAwait(false); if (!canRetry) { if ((Uri)null != this._actualUrl && this._actualUrl != this._segment.Url) { this._actualUrl = (Uri)null; } else { this._response.EnsureSuccessStatusCode(); } } this._response.Dispose(); this._response = (IWebStreamResponse)null; } else { break; } } this._actualUrl = this._response.ActualUrl; long?contentLength = this._response.ContentLength; if (!this._endOffset.HasValue) { nullable1 = contentLength; long?nullable3; if (!nullable1.HasValue) { nullable2 = new long?(); nullable3 = nullable2; } else { nullable3 = new long?(nullable1.GetValueOrDefault() - 1L); } this._endOffset = nullable3; } if (!this._expectedBytes.HasValue) { this._expectedBytes = contentLength; } SegmentReader segmentReader1 = this; ConfiguredTaskAwaitable <Stream> configuredTaskAwaitable = this._response.GetStreamAsync(cancellationToken).ConfigureAwait(false); PositionStream positionStream = new PositionStream(await configuredTaskAwaitable); segmentReader1._responseStream = (Stream)positionStream; Task <Stream> filterStreamTask = this._segment.CreateFilterAsync(this._responseStream, cancellationToken); if (null != filterStreamTask) { SegmentReader segmentReader2 = this; configuredTaskAwaitable = filterStreamTask.ConfigureAwait(false); Stream stream = await configuredTaskAwaitable; segmentReader2._readStream = stream; } else { this._readStream = this._responseStream; } ISegmentMetadata segmentMetadata = this._webMetadataFactory.CreateSegmentMetadata(webResponse, (ContentType)null); setMetadata(segmentMetadata); }), cancellationToken)); }
public async Task <int> ReadAsync(byte[] buffer, int offset, int length, Action <ISegmentMetadata> setMetadata, CancellationToken cancellationToken) { this.ThrowIfDisposed(); int index = 0; int thresholdSize = length - length / 4; int retryCount = 3; int delay = 200; int num1; using (CancellationTokenSource linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(this._disposedCancellationTokenSource.Token, cancellationToken)) { do { if (null == this._readStream) { await this.OpenStream(setMetadata, cancellationToken).ConfigureAwait(false); } Debug.Assert(null != this._readStream); bool retry = false; try { int count = await this._readStream.ReadAsync(buffer, offset + index, length - index, linkedTokenSource.Token).ConfigureAwait(false); if (count < 1) { if (!this.IsLengthValid()) { throw new WebException(string.Format("Read length mismatch mismatch ({0} expected)", (object)this._expectedBytes)); } this.IsEof = true; this.Close(); num1 = index; goto label_26; } else { retryCount = 3; if (!this._startOffset.HasValue) { this._startOffset = new long?((long)count); } else { SegmentReader segmentReader = this; long? nullable1 = segmentReader._startOffset; long num2 = (long)count; long? nullable2 = nullable1.HasValue ? new long?(nullable1.GetValueOrDefault() + num2) : new long?(); segmentReader._startOffset = nullable2; } index += count; } } catch (OperationCanceledException ex) { this.Close(); throw; } catch (Exception ex) { Debug.WriteLine("Read of {0} failed at {1}: {2}", (object)this._segment.Url, (object)this._startOffset, (object)ex.Message); this.Close(); if (--retryCount <= 0) { throw; } else { retry = true; } } if (retry) { int actualDelay = (int)((double)delay * (0.5 + this._platformServices.GetRandomNumber())); delay += delay; await TaskEx.Delay(actualDelay, linkedTokenSource.Token).ConfigureAwait(false); } }while (index < thresholdSize); } num1 = index; label_26: return(num1); }