private void AsyncEndRead(IAsyncResult asyncResult) { Debug.Assert(asyncResult != null && asyncResult.IsCompleted, "asyncResult.IsCompleted"); AsyncStateBag asyncStateBag = asyncResult.AsyncState as AsyncStateBag; PerRequest pereq = asyncStateBag == null ? null : asyncStateBag.PerRequest; int count = 0; try { this.CompleteCheck(pereq, InternalError.InvalidEndReadCompleted); pereq.SetRequestCompletedSynchronously(asyncResult.CompletedSynchronously); // BeginRead this.SetCompletedSynchronously(asyncResult.CompletedSynchronously); Stream httpResponseStream = Util.NullCheck(pereq.ResponseStream, InternalError.InvalidEndReadStream); // get the http response stream. Stream outResponseStream = Util.NullCheck(this.outputResponseStream, InternalError.InvalidEndReadCopy); byte[] buffer = Util.NullCheck(this.asyncStreamCopyBuffer, InternalError.InvalidEndReadBuffer); count = httpResponseStream.EndRead(asyncResult); this.usingBuffer = false; if (count > 0) { outResponseStream.Write(buffer, 0, count); } if (count > 0 && buffer.Length > 0 && httpResponseStream.CanRead) { if (!asyncResult.CompletedSynchronously) { // if CompletedSynchronously then caller will call and we reduce risk of stack overflow this.ReadResponseStream(asyncStateBag); } } else { // Debug.Assert(this.ContentLength < 0 || outResponseStream.Length == this.ContentLength, "didn't read expected ContentLength"); if (outResponseStream.Position < outResponseStream.Length) { // In Silverlight, generally 3 bytes less than advertised by ContentLength are read ((MemoryStream)outResponseStream).SetLength(outResponseStream.Position); } pereq.SetComplete(); this.SetCompleted(); } } catch (Exception e) { if (this.HandleFailure(e)) { throw; } } finally { this.HandleCompleted(pereq); } }
protected bool HandleFailure(PerRequest pereq, Exception e) { if (pereq != null) { if (this.IsAborted) { pereq.SetAborted(); } else { pereq.SetComplete(); } } return(this.HandleFailure(e)); }
protected override void AsyncEndGetResponse(IAsyncResult asyncResult) { Debug.Assert(asyncResult != null && asyncResult.IsCompleted, "asyncResult.IsCompleted"); AsyncStateBag asyncStateBag = asyncResult.AsyncState as AsyncStateBag; PerRequest pereq = asyncStateBag == null ? null : asyncStateBag.PerRequest; try { if (this.IsAborted) { if (pereq != null) { pereq.SetComplete(); } this.SetCompleted(); } else { this.CompleteCheck(pereq, InternalError.InvalidEndGetResponseCompleted); pereq.SetRequestCompletedSynchronously(asyncResult.CompletedSynchronously); this.SetCompletedSynchronously(asyncResult.CompletedSynchronously); ODataRequestMessageWrapper requestMessage = Util.NullCheck(pereq.Request, InternalError.InvalidEndGetResponseRequest); // the httpWebResponse is kept for batching, discarded by non-batch IODataResponseMessage response = this.RequestInfo.EndGetResponse(requestMessage, asyncResult); pereq.ResponseMessage = Util.NullCheck(response, InternalError.InvalidEndGetResponseResponse); this.SetHttpWebResponse(pereq.ResponseMessage); Debug.Assert(null == pereq.ResponseStream, "non-null async ResponseStream"); Stream httpResponseStream = null; if (HttpStatusCode.NoContent != (HttpStatusCode)response.StatusCode) { httpResponseStream = response.GetStream(); pereq.ResponseStream = httpResponseStream; } if ((null != httpResponseStream) && httpResponseStream.CanRead) { if (null == this.outputResponseStream) { // this is the stream we copy the reponse to this.outputResponseStream = Util.NullCheck(this.GetAsyncResponseStreamCopy(), InternalError.InvalidAsyncResponseStreamCopy); } if (null == this.asyncStreamCopyBuffer) { // this is the buffer we read into and copy out of this.asyncStreamCopyBuffer = Util.NullCheck(this.GetAsyncResponseStreamCopyBuffer(), InternalError.InvalidAsyncResponseStreamCopyBuffer); } // Make async calls to read the response stream this.ReadResponseStream(asyncStateBag); } else { pereq.SetComplete(); this.SetCompleted(); } } } catch (Exception e) { if (this.HandleFailure(e)) { throw; } } finally { this.HandleCompleted(pereq); } }