/// /// Response callback private static void ResponseCallback(IAsyncResult result) { QueueEntry entry = (QueueEntry)result.AsyncState; #pragma warning disable 6500 // Catch all exceptions and marshal them to the correct thread try { WebResponse response = WpfWebRequestHelper.EndGetResponse(entry.webRequest, result); entry.inputStream = response.GetResponseStream(); entry.contentLength = response.ContentLength; entry.contentType = response.ContentType; entry.webRequest = null; // GC the WebRequest _workQueue.Enqueue(entry); // Signal _waitEvent.Set(); } catch (Exception e) { MarshalException(entry, e); } #pragma warning restore 6500 }
/// <summary> /// ResponseCallBack /// </summary> /// <param name="ar">async result</param> /// <remarks>static method not necessary</remarks> private void ResponseCallback(IAsyncResult ar) { HttpWebResponse webResponse = null; lock (_syncObject) { try { if (_disposed) { return; } // The caller thread can dispose this class and the worker thread need to check the disposed // condition; need to lock // If disposed, there is nothing to handle webResponse = (HttpWebResponse)WpfWebRequestHelper.EndGetResponse(_webRequest, ar); // If it is not partial content, no need to look further if (webResponse.StatusCode == HttpStatusCode.PartialContent) { // // Check for few conditions // // Get the header and make sure that it was indeed the byte range response int beginOffset = _byteRangesInProgress[0, Offset_Index]; int endOffset = beginOffset + _byteRangesInProgress[0, Length_Index] - 1; // HttpWebRequest in the current CLR does not allow multiple byte range requests. // At this point, none of the callers of this class will make more than one range at a time // So, we should not receive any response with more than one range returned // When multiple byte ranges requests are support in HttpWebRequest eventually, // there is a question on how to handle multipart response (Content-Type=multipart/byteranges) // At this point we only need to handle one byte range response (Content-Range header) only // Request was successful // Note: endOffset could be trimmed offset in the case where the response didn't // satisfy the entire request if (CheckContentRange(webResponse.Headers, beginOffset, ref endOffset)) { // Write out the bytes to the temp file if (WriteByteRange(webResponse, beginOffset, endOffset - beginOffset + 1)) { // The range is downloaded successfully; add it to the list _byteRangesAvailable.Add(beginOffset); _byteRangesAvailable.Add(endOffset - beginOffset + 1); } else { _erroredOut = true; } } else { _erroredOut = true; _erroredOutException = new NotSupportedException(SR.Get(SRID.ByteRangeRequestIsNotSupported)); } } else { _erroredOut = true; } } catch (Exception e) // catch (and re-throw) exceptions so we can inform the other thread { _erroredOut = true; _erroredOutException = e; throw e; } catch // catch (and re-throw) all kinds of exceptions so we can inform the other thread { // inform other thread of error condition _erroredOut = true; _erroredOutException = null; throw; } finally { if (webResponse != null) { webResponse.Close(); } // bytes requested are downloaded or errored out // inform the caller that these ranges are available RaiseEvent(!_erroredOut); } // If we haven't errored out already, process the next batch if (!_erroredOut) { ProcessWaitQueue(); } } }